0

我有一个方法

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

在我的 WPF 代码后面和我的 XAML 页面中,我有一个选项卡控件。函数的参数指定应该关注哪个 tabitem。我想在同一解决方案的类文件中调用此方法。但是当我尝试调用这个方法时,NewChatWindow.selectingTab(clientName)我得到了一个错误,比如需要对象引用。当我尝试为窗口创建一些对象并调用类似的方法时

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

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

4

3 回答 3

2

这里发生了件事......

当涉及控件(例如您的选项卡控件)时,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 Cross Thread Object Access

...以及这里如何处理跨线程访问异常?

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

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

**

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

**

于 2013-10-19T17:02:23.237 回答
0

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

  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 单线程单元)。假设您的线程是异步的,这篇文章可能会对您有所帮助:异步编程的最佳实践

于 2013-10-19T17:10:44.710 回答
0

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

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

于 2013-10-19T17:14:32.523 回答