InvalidOperationException,调用线程应该是STA因为

时间:2014-06-19 14:16:01

标签: c# wpf mvvm invalidoperationexception

我正在开发一个项目,以便用几种模态(鼠标,leapmotion,touch ......)操纵很多对象。我使用MVVM模式制作它,所以我将使用几个视图和ViewModel用于我将使用的所有组件。为了更容易开发,我选择了一个Canvas组件,我将在其中操作网格。每个网格都可以包含任何类型的对象(形状,文本,图像,文档......)。

为了能够将所有模态与我的方法相关联,我决定为每个模态构建一个监听器(1个用于鼠标,1个用于leapmotion ......)并使它们检测基本手势(如Click,DoubleClick .. )。我选择检测的所有手势都通过词典与方法相关联。无论如何,链接正在按预期工作,因为它执行正确的方法。举个例子我在我的鼠标监听器中调用了动作:

if (_leftClickCounter == 1 && _capturedLeft == false)
{
    if (_dic.ContainsKey(Key.OnClick))
    {
        Action<object> action = _dic[Key.OnClick];
        action.Invoke(null);
    }
}

其中:

  • _dic是我的字典
  • 键入手势的枚举(如OnClick,OnDoubleClick ...)
  • 操作执行方法

在我的例子中,执行的方法是:

public void Add(object sender)
{
    ObjectModel objectModel = new ObjectModel();
    ObjectView objectView = new ObjectView(objectModel);
    this.objectViews.Add(objectView);
}

发件人仅用于测试目的。它在该方法中仍未使用。当我尝试实例化我的ObjectView时,我的执行停止了:

InvalidOperationException
The calling thread must be STA, because many UI components require this

我的ObjectView.xaml.cs类是:

public partial class ObjectView : UserControl
{
    public ObjectView(ObjectModel obj)
    {
        InitializeComponent();

        EventLinker linker = new EventLinker(this.visualBox);
        ObjectViewModel objectVM = new ObjectViewModel(obj, linker);
        this.DataContext = objectVM;
    }
}

定义要使用的UserControl的ObjectView.xaml非常基本:

<UserControl x:Class="AusyTouchMultimodal_v1.View.ObjectView"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300">

     <Grid x:Name="visualBox" Background="Blue"/>

</UserControl>

我没有任何编译错误,只是这个InvalidOperationException。有人可以向我解释这个问题吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

尝试在ui线程中调用您的操作,就像这样

if (_leftClickCounter == 1 && _capturedLeft == false)
{
    if (_dic.ContainsKey(Key.OnClick))
    {
        Action<object> action = _dic[Key.OnClick];
        // action.Invoke(null);         
        System.Windows.Application.Current.Dispatcher.BeginInvoke( call your action )
    }
}