在样式中自定义TextBox右键菜单,多线程错误。

5
在WPF应用程序中,我使用自定义样式的文本框,其中ContextMenu被覆盖,如下所示:
  <Style TargetType="{x:Type TextBox}">
    <Setter Property="ContextMenu">
      <ContextMenu>
        <MenuItem Header="Copy"/>
      </ContextMenu>
    </Setter>
  </Style>

这段代码在单线程中可以完美运行,但是如果我在不同的线程中运行带有TextBox的窗口,则会出现问题:
Thread thread = new Thread(()=>
                                {
                                TestWindow wnd = new TestWindow();
                                wnd.ShowDialog();
                                });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();

但是这会导致InvalidOperationException "调用线程无法访问此对象,因为不同的线程拥有它。".

如何避免这个问题?

2个回答

5
问题在于您的样式被重复使用以进行优化,因此ContextMenu被重复使用 - 这是标准做法,并且对单线程工作良好,但对多线程不起作用。
建议将样式移动到ResourceDictionary中,并引用它作为StaticResource,然后标记为: x:Shared="false" 每次访问资源时都会创建一个新实例 - 我不确定它是否适用于您拥有的“catch all”无键样式。 然后,您可以将ContextMenu制作成资源,并将其引用为StaticResource - 就可以解决问题了。

另一种解决方案是使用事件设置器来处理右键单击,并动态创建一个上下文菜单。 - Rune Andersen

0

在你的代码中,你想要在非 UI 线程中修改 UI,这是不允许的。

你必须确保在应用 UI 更新时处于 UI 线程上。你可以通过检查 object.InvokeRequired 的值来确定是否需要这样做。如果需要,你可以通过调用 object.Invoke([delegate]) 来调用该方法。

此外,你还可以使用调度程序,请参见 MSDNthis blog。祝阅读愉快。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接