我已经创建了一个应用程序,需要大量的访问UI控件,现在我首先要做的是创建一个可扩展的接口,特别是我创建了不同的控件UserControl
和一个类ViewModel
,管理这个控件的所有方法来更新UI。实际上,在Main
线程中所有工作都很好。特别是以下场景工作完美:
MainWindow XAML
xmlns:MyControls="clr-namespace:HeavyAPP"
...
<!-- I use the control in the following way: -->
<Grid>
<MyControls:Scheduler x:Name="Sc"/>
</Grid>
例如,Scheduler
控件包含以下Data Binding
:
<StackPanel Orientation="Horizontal">
<Label x:Name="NextSync" Content="{Binding NextSynchronization, IsAsync=True}" ></Label>
</StackPanel>
ViewModel结构
public class ViewModelClass : INotifyPropertyChanged
{
private CScheduler scheduler;
public ViewModelClass()
{
scheduler = new Scheduler();
}
public string NextSynchronization
{
get
{
return scheduler.GetNextSync();
}
}
}
在ViewModel
中你可以看到我有一个Scheduler
控件的示例和一个名为NextSyncrhonization
的property
作为binding
,所以这个属性从控件示例的方法返回一个结果。
为了在MainWindow
中使用它,我做了以下操作:
public MainWindow()
{
ViewModelClass viewModel = new ViewModelClass();
DataContext = viewModel;
}
这将自动填充控件属性。现在的问题是,我使用一个BackgroundWorker
来执行一些任务,我需要的是使用不同类的DataContext
或MainWindow
(不是Window,而是类)。
为了解决这个问题,我想做这样的事情:
MainWindow.AppWindow.Sc.SyncLog.Dispatcher.Invoke(
new Action(() =>
{
ViewModelClass viewModel = new ViewModelClass();
var dataContext = System.Windows.Application.Current.MainWindow.DataContext;
dataContext = viewModel;
viewModel.SynchronizationLog = "this is a test from other thread"}));
现在SynchronizationLog
是另一个附加文本到Control的属性,只是为了精确,是这样的:
private string _text;
public string SynchronizationLog
{
get
{
return _text += _text;
}
set
{
_text = value;
OnPropertyChanged();
}
}
这是INotifyPropertyChanged的实现:
`public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}`
这只在MainWindow
中工作,但在外部类中我不能更新UI,我做错了什么?
不管怎样,我不认为有什么错误。
1条答案
按热度按时间lfapxunr1#
尝试以下操作:
如下扩展ViewModel:
这会将xaml.cs中的代码更改为:
在你的外部代码中,你不会创建一个
ViewModelClass
的新示例,而是使用现有的示例:基本上,您在这里所做的就是从ViewModel外部设置ViewModel中的属性。这可以从任何地方进行。
与您的方法有何不同:
1.我们不创建ViewModel的新示例(UI中的不同绑定不再重置)
1.我们创建了一个
Instance
,因此一次只能有一个viewModel