在 WPF 代码中调用不特定于 UI 的方法

本文关键字:UI 方法 WPF 代码 调用 | 更新日期: 2023-09-27 18:36:06

我有一个方法

public void selectingTab(string name)
{
   //Code to select a particular tabitem in the XAML based on the parameter name
}`

在我的 WPF 代码隐藏和 XAML 页面中,我有一个选项卡控件。函数的参数指定应将哪个选项卡项置于焦点。我想在同一解决方案的类文件中调用此方法。但是当我尝试调用此方法时NewChatWindow.selectingTab(clientName)会收到一个错误,例如需要对象引用。当我尝试为窗口创建一些对象并调用类似

NewChatWindow win = new NewChatWindow();
win.selectingTab(clientName);

收到错误"调用线程必须是 STA,因为许多 UI 组件"。我该怎么做。提前谢谢。

在 WPF 代码中调用不特定于 UI 的方法

这里有

件事...

当涉及控件(如选项卡控件)时,UI 线程无法与源自其他线程的活动交互。 为了避免跨线程问题,请使用这样的构造...

  private void DoSomethingOnTheUiThread()
        {
            Dispatcher.BeginInvoke((Action) (() =>
                {
                    // your code goes here...
                    Window w = new Window();
                    w.Show();
                }));
        }

。其中"调度程序"获取与窗口关联的System.Windows.Threading.Dispatcher。每个UIElement都有一个用于此目的的调度程序。BeginInvoke 计划委托在 UI 线程上运行。

相关的 SO 问题在此处提供了更多见解:WPF 跨线程对象访问

。和这里 如何处理跨线程访问异常?

对于您的其他问题,让我们看看您的代码...

Task.Factory.StartNew(() => 
{
   NewWindow.selectingTab(ClientName); 
   using (var ns = cl.GetStream()) 
   using (var br = new BinaryReader(ns)) 
   using (var bw = new BinaryWriter(ns)) 
   { 
      Console.WriteLine("Message from client is " + br.ReadString() + " from " + clientName); } }); 

在你的评论中,你指出"NewWindow"是一个类。 但是您调用的是"NewWindow"的实例方法,而不是"NewWindow"的静态方法。 所以编译器对此有所抱怨。

要调用实例方法,必须先创建一个实例,如下所示...

NewWindow nw = new NewWindow();
nw.selectedTab("some name");

c# 祖先将语法"NewWindow.selectedTab"表示为静态方法。 我不知道您要实现其中的哪一个,但您需要选择一个与您的使用情况一致的方法。

相关文档在这里:http://msdn.microsoft.com/en-US/library/aa645766(v=vs.71).aspx

**

当在成员访问(第 7.5.4 节)中引用方法时 形式 E.M,如果 M 是静态方法,E 必须表示包含 M 的类型, 如果 M 是实例方法,则 E 必须表示类型的实例 包含 M。

**

我假设您在运行时使用反射来获取属性信息。通过调用实例方法的方式,您可能会收到需要对象引用错误(非静态字段方法或属性需要对象引用)。在您包含省略的代码之前,我们只能猜测发生此错误的原因。

  1. 如果要引用 XAML 中的对象,则需要 x:Name 指令(WPF 中的 x:Name 指令)。

下面是 WPF 部件的示例:

<StackPanel DockPanel.Dock="Right" Background="Yellow" MinWidth="150" Margin="2" x:Name="StackPanelRight"></StackPanel>

然后,可以从代码隐藏中引用命名属性。

        StackPanel sp = new StackPanel();
        StackPanel btnSP = new StackPanel();
        btnSP.Orientation = Orientation.Horizontal;
        btnSP.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
        btnSP.Children.Add(btn3);
        btnSP.Children.Add(btn4);
        sp.Children.Add(btnSP);
        StackPanelRight.Children.Add(sp);

STA 代表 单线程公寓。STA是在COM时代创造的(了解COM单线程公寓)。假设线程是异步的,本文可能会帮助你: 异步编程的最佳实践。

为了利用WPF功能和优势,我建议使用MVVM模式。如果后台线程启动更改,则可以从模型通知中修改 UI(选择所需的选项卡)事件。

有关 MVVM 模式的更多信息:此线程