Tad*_*ada 0 c# wpf mvvm backgroundworker viewmodel
我一直在使用WPF中的MVVM,并且对于人们有一个快速的问题.现在我有:
我在UserControl中公开了对Grid Properties的访问,但是User Control不知道什么也不与MainWindow交互.
我还有一个我调用ViewModel的类,它为我操作MainWindow/UserControl.我的理解是ViewModel知道View(MainWindow/UserControl)以及如何操作它,而View通常对ViewModel一无所知.
如果我有这个权利,这是我的问题:
当我按下MainWindow MenuBar上的按钮时,我想执行操作.现在,这些操作必然会在MainWindow中说一个EventHandler,并且EventHandler实例化ViewModel并调用方法进行处理,如下所示:
private void RunQueryMenuItemAdvClick(object pSender, RoutedEventArgs pRoutedEventArgs)
{
ViewModel vViewModel = new ViewModel(this);
vViewModel.RunQuery();
}
Run Code Online (Sandbox Code Playgroud)View Model看起来像这样:
public class ViewModel
{
private DataProvider fDataProvider;
private MainWindow fMainWindow;
private BackgroundWorker fQueryWorker = new BackgroundWorker();
public ViewModel(MainWindow pMainWindow)
{
fDataProvider = new DataProvider();
fMainWindow = pMainWindow;
//Query Worker
fQueryWorker.DoWork += QueryWorkerDoWork;
fQueryWorker.RunWorkerCompleted += QueryWorkerCompleted;
}
private void QueryWorkerCompleted(object pSender, RunWorkerCompletedEventArgs pRunWorkerCompletedEventArgs)
{
fMainWindow.UserControl_Data.busyIndicator1.IsBusy = false;
fMainWindow.UserControl_Data.DataToPresent = pRunWorkerCompletedEventArgs.Result;
}
private void QueryWorkerDoWork(object pSender, DoWorkEventArgs pDoWorkEventArgs)
{
pDoWorkEventArgs.Result = this.fDataProvider.GetParticipantsData();
}
public void RunQuery()
{
if (!fQueryWorker.IsBusy)
{
fMainWindow.UserControl_Data.busyIndicator1.IsBusy = true;
fQueryWorker.RunWorkerAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的方法在这里偏离基础吗?
编辑新解决方案: 首先,感谢大家的回应.我想提供我的新解决方案.这可能不是100%的MVVM,但它必须至少比我的好80%!
我的ViewModel:
public class ViewModel : ObservableObject
{
private DataProvider fDataProvider;
private BackgroundWorker fQueryWorker = new BackgroundWorker();
public ViewModel()
{
fDataProvider = new DataProvider();
//Query Worker
fQueryWorker.DoWork += QueryWorkerDoWork;
fQueryWorker.RunWorkerCompleted += QueryWorkerCompleted;
}
//This is my Command for the MainWindow.MenuItem to bind to to run a query
RelayCommand fRunQueryCommand;
public ICommand RunQueryCommand
{
get
{
if (this.fRunQueryCommand == null)
{
this.fRunQueryCommand = new RelayCommand(param => this.RunQuery(),
param => true);
}
return this.fRunQueryCommand;
}
}
//This is my Property for the UserControl.progressBar to bind to
private bool fIsBusy;
public bool IsBusy
{
get { return this.fIsBusy; }
set
{
if (value != this.fIsBusy)
{
this.fIsBusy = value;
OnPropertyChanged("IsBusy");
}
}
}
//This is my Property for the UserControl.gridControl.ItemSource to bind to
private object fSource;
public object Source
{
get { return this.fSource; }
set
{
if (value != this.fSource)
{
this.fSource = value;
OnPropertyChanged("Source");
}
}
}
private void QueryWorkerCompleted(object pSender, RunWorkerCompletedEventArgs pRunWorkerCompletedEventArgs)
{
this.IsBusy = false;
Source = pRunWorkerCompletedEventArgs.Result;
}
private void QueryWorkerDoWork(object pSender, DoWorkEventArgs pDoWorkEventArgs)
{
pDoWorkEventArgs.Result = this.fDataProvider.GetParticipantsData();
}
public void RunQuery()
{
if (!fQueryWorker.IsBusy)
{
this.IsBusy = true;
fQueryWorker.RunWorkerAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
我已经从MainWindow和UserControl后面删除了所有代码,并将其替换为XAML,用于将我需要的元素绑定到ViewModel和1 Command中的两个属性.请随意提供有关我可能会或可能没有重新考虑因素的额外反馈.(除了缺乏模型用法).
你离这里很远.
反过来说:View了解ViewModel,而ViewModel对View一无所知.
在ViewModel中引用MainWindow和UserControl 不是 MVVM.
使用MVVM时,通常没有点击处理程序.
处理这种情况的正确方法如下:
RunQuery,但您只需将IsBusy ViewModel设置 为true即可.然后,UserControl将绑定到该属性.所有这些都可以通过将DataContextView 设置为ViewModel的实例来实现.
| 归档时间: |
|
| 查看次数: |
544 次 |
| 最近记录: |