C# 在接收消息时创建视图

C# 在接收消息时创建视图,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一个MVVM视图和viewmodel。在viewmodel的构造函数中,我传递一个IObservable消息列表,并通过viewmodel和view之外的一个简单类订阅它们 课外 { viewModel = new ViewModelClass( responseHandler.AsObservable()); viewModel.PropertyChanged += ViewModel_PropertyChang

我有一个MVVM视图和viewmodel。在viewmodel的构造函数中,我传递一个IObservable消息列表,并通过viewmodel和view之外的一个简单类订阅它们

课外

{
     viewModel =
            new ViewModelClass(
                responseHandler.AsObservable());

     viewModel.PropertyChanged += ViewModel_PropertyChanged;
 }

 private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
 {

     if (e.PropertyName == nameof(ViewModelClass.MyProperty))
     {
         // Error here
         view = new MyViewClass() { DataContext = viewModel };

     }
 }
在视图模型构造函数中

        subscription = receiveMessages.Subscribe(MessageReceived);

        private void MessageReceived(GvsMessage message)
        {
            MyProperty = true;

        }
收到消息后,我想创建我的视图,而不是在此之前。尽管viewmodel是在处理属性更改等之前创建的


问题是我得到了“调用线程必须是sta,因为许多ui组件都需要它”。请有人帮忙

正如我们在评论中所说的那样,您需要使用可从应用程序的不同部分获取的
调度程序。
要初始化dispatcher,可以使用以下代码段:

protected static Dispatcher _d;
if (Application.Current != null)
{
   _d = Application.Current.Dispatcher;
}
else
{
   _d = Dispatcher.CurrentDispatcher;
}  
说明:
当应用程序具有
UnitTests
时,将执行第一个调度程序。当您运行测试时,此调度程序将不为null,
第二个是应用程序使用的当前
调度程序

在初始化
VM
时,在代码中包含了这些内容后,现在可以将消息
操作
事件
发送到UI线程。
我有一个小方法:

public static void UIThread(Action action)
    {
        if (_d == null)
        {
            if (Application.Current != null)
            {
                _d = Application.Current.Dispatcher;
            }
            else
            {
                _d = Dispatcher.CurrentDispatcher;
            }
        }
        _d.Invoke(action);
    }  
此函数将接受lambda,如下所示:

UIThread(() =>
        {
            Processing = true;
            Message = "Working ...";
            //in your case you would raise the Loaded event here
        });  
这样,视图中的
EventHandler
就可以显示该视图了。
如果您需要更多信息,请告诉我们。

HTH

正如我们在评论中所说的,您需要使用一个
调度程序,它可以从应用程序的不同部分获取。
要初始化dispatcher,可以使用以下代码段:

protected static Dispatcher _d;
if (Application.Current != null)
{
   _d = Application.Current.Dispatcher;
}
else
{
   _d = Dispatcher.CurrentDispatcher;
}  
说明:
当应用程序具有
UnitTests
时,将执行第一个调度程序。当您运行测试时,此调度程序将不为null,
第二个是应用程序使用的当前
调度程序

在初始化
VM
时,在代码中包含了这些内容后,现在可以将消息
操作
事件
发送到UI线程。
我有一个小方法:

public static void UIThread(Action action)
    {
        if (_d == null)
        {
            if (Application.Current != null)
            {
                _d = Application.Current.Dispatcher;
            }
            else
            {
                _d = Dispatcher.CurrentDispatcher;
            }
        }
        _d.Invoke(action);
    }  
此函数将接受lambda,如下所示:

UIThread(() =>
        {
            Processing = true;
            Message = "Working ...";
            //in your case you would raise the Loaded event here
        });  
这样,视图中的
EventHandler
就可以显示该视图了。
如果您需要更多信息,请告诉我们。

我通过在构造函数中创建视图和viewmodel解决了这个问题。在propertychanged事件中,我刚刚将属性IsVisible设置为“true”,以绑定窗口可见性

<Window.Visibility>
    <Binding Path="IsVisible" Converter="{StaticResource BoolToVisibilityConverter}" Mode="TwoWay"/>
</Window.Visibility>

我通过在构造函数中创建视图和视图模型解决了这个问题。在propertychanged事件中,我刚刚将属性IsVisible设置为“true”,以绑定窗口可见性

<Window.Visibility>
    <Binding Path="IsVisible" Converter="{StaticResource BoolToVisibilityConverter}" Mode="TwoWay"/>
</Window.Visibility>


我们需要更多信息,因为这里有MT(多线程)。我们不需要详细的示例,只需要我们能够理解应用程序是如何构建的。外部类位于线程中,这就是我无法在ViewModel_PropertyChanged中更改视图(创建视图等)的原因。我尝试了一个黑客程序,设置了一个计时器来检查我的财产是否发生了变化,它是否正常工作。但是什么是好的方法呢?创建事件也会产生同样的问题OK,您的
视图需要在
主UI线程中创建。所有的数据处理都可以在
后台线程中完成,否则
WPF
将不喜欢它,因为如果在非UI线程中创建
UserControl
,该线程就是它创建的对象的所有者。我尝试在主线程中创建视图,但在收到消息之前我不想显示它。即使在ViewModel_PropertyChanged中显示视图,也会出现错误。我尝试调用事件,但除了我必须在主线程中进行轮询外,其他功能均无效。据我所知,您需要在另一个线程中创建视图模型,然后在视图模型上订阅事件,让我们将其称为
Loaded
,然后您必须使用
Dispatcher
来引发加载的事件,这样它就是引发它的同一个线程。如果你愿意,我可以给你举个例子。我们需要更多信息,因为这里有MT(多线程)。我们不需要详细的示例,只需要我们能够理解应用程序是如何构建的。外部类位于线程中,这就是我无法在ViewModel_PropertyChanged中更改视图(创建视图等)的原因。我尝试了一个黑客程序,设置了一个计时器来检查我的财产是否发生了变化,它是否正常工作。但是什么是好的方法呢?创建事件也会产生同样的问题OK,您的
视图需要在
主UI线程中创建。所有的数据处理都可以在
后台线程中完成,否则
WPF
将不喜欢它,因为如果在非UI线程中创建
UserControl
,该线程就是它创建的对象的所有者。我尝试在主线程中创建视图,但在收到消息之前我不想显示它。即使在ViewModel_PropertyChanged中显示视图,也会出现错误。我尝试调用事件,但除了我必须在主线程中进行轮询外,其他功能均无效。据我所知,您需要在另一个线程中创建视图模型,然后在视图模型上订阅事件,让我们将其称为
Loaded
,然后您必须使用
Dispatcher
来引发加载的事件,这样它就是引发它的同一个线程。如果你愿意,我可以给你举个例子。