【发布时间】:2016-05-19 10:22:30
【问题描述】:
我创建了一个需要大量访问 UI 控件的应用程序,现在我首先要做的是创建一个可扩展的界面,特别是我创建了不同的控件,如 UserControl 和一个类 ViewModel 来管理所有方法此控件用于更新 UI。实际上在Main 线程中一切正常。特别是以下场景完美运行:
主窗口 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 来执行某些任务,我需要的是使用来自不同类的MainWindow 的DataContext(不是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 是另一个将文本附加到控件的属性,只是为了精确,是这样的:
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,我做错了什么?
无论如何,我没有收到任何错误。
【问题讨论】: