我一直在使用WPF中的MVVM,併爲人們提供了一個快速的問題。現在,我有:在WPF中查看和查看模型
- 主窗口它由一個菜單欄和一個用戶控件
- 用戶控件(上述)的基本上包含一個網格。
我公開對網格屬性的訪問,因爲我需要在UserControl中,但用戶控件一無所知,也不與MainWindow交互。
我也有一個類,我調用ViewModel,它爲我操作MainWindow/UserControl。我的理解是,ViewModel知道View(MainWindow/UserControl)以及如何操作它,而View通常對ViewModel一無所知。
如果我有這個權利,這是我的問題:
當我在主窗口菜單欄按鈕點擊我要執行的操作。現在,這些措施在不能不說,在主窗口一個事件處理程序和事件處理程序實例化視圖模型,並調用方法來處理類似這樣的:
private void RunQueryMenuItemAdvClick(object pSender, RoutedEventArgs pRoutedEventArgs) { ViewModel vViewModel = new ViewModel(this); vViewModel.RunQuery(); }
視圖模型看起來是這樣的:
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();
}
}
}
我在這裏以我的方式脫離基地嗎?
編輯新的解決方案: 首先,感謝大家的響應。我想提供我的新解決方案。這可能不是100%的MVVM,但它至少要比我的好80%!
我的視圖模型:
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();
}
}
我和XAML刪除了所有我的代碼從主窗口和用戶控件後面,取代它綁定,我需要在視圖模型的兩個屬性和1的元素命令。隨意提供額外的反饋,說明我可能會或可能沒有選擇重新分解。 (除了缺少模型使用)。
感謝您的答覆。我一直在通過一些重構來完成整理。快速提問 - 我想將控件的屬性綁定到ViewModel的IsBusy屬性,但是,我沒有爲UserControl設置「DataContext」。我明白這個錯誤,但是爲MainControlow中的UserControl設置上下文的正確方法是什麼(誰已經設置了DataContext) – Tada
@Tada DataContext被繼承,所以如果你的MainWindow有一個'你的'ViewModel'的DataContext',那麼你的'ContentControl'也會有''ViewModel''的DataContext,假設你沒有設置它。我的博客中實際上有一個[數據上下文的概述](http://rachel53461.wordpress.com/2012/07/14/what-is-this-datacontext-you-speak-of/),以及你可能有興趣閱讀:) – Rachel
@Rachel - 感謝您的回覆。你的博客很棒。非常容易閱讀和理解!保持這些博客,並不斷回答我的問題!我的問題不像我想的那樣是DataContext,實際上是我忘了繼承ObserverableObject類並引發屬性更改! – Tada