C# 在接收消息时创建视图
我有一个MVVM视图和viewmodel。在viewmodel的构造函数中,我传递一个IObservable消息列表,并通过viewmodel和view之外的一个简单类订阅它们 课外C# 在接收消息时创建视图,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一个MVVM视图和viewmodel。在viewmodel的构造函数中,我传递一个IObservable消息列表,并通过viewmodel和view之外的一个简单类订阅它们 课外 { viewModel = new ViewModelClass( responseHandler.AsObservable()); viewModel.PropertyChanged += ViewModel_PropertyChang
{
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
来引发加载的事件,这样它就是引发它的同一个线程。如果你愿意,我可以给你举个例子。