我只是想掌握 WPF 中的 MVVM 模式(目前没有任何框架)。
场景:
我有一个主窗口,单击“开始工作”按钮,该按钮绑定(bind)到 View 模型中的某个命令。进度对话框应该打开“取消”按钮,它应该显示在所有者窗口的中心(所以我需要传递所有者),我按下取消并在后台工作人员上调用“CancelAsync”方法。
MVVM 的原则是 View 模型永远不应该知道关于 View 的任何信息,在我的情况下,我违反了这条规则。
代码隐藏(无 MVVM)解决方案:
主窗口部分:
private void Button_Click(object sender, RoutedEventArgs e)
{
backgroundWorker.RunWorkerAsync();
progressWindow = new ProgressWindow(backgroundWorker);
progressWindow.Owner = this;
progressWindow.ShowDialog();
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressWindow.Close();
}
进度窗口部分:
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
backgroundWorker.CancelAsync();
}
我尝试将此代码转换为 MVVM(这是错误的)
public class MainViewModel
{
public ICommand DoSomething { get; }
private BackgroundWorker backgroundWorker;
private PleaseWaitView pleaseWaitView;
public MainViewModel()
{
backgroundWorker = new BackgroundWorker() { WorkerSupportsCancellation = true };
backgroundWorker.DoWork += BackgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
var pleaseWaitViewModel = new PleaseWaitViewModel(backgroundWorker);
pleaseWaitView = new PleaseWaitView();
pleaseWaitView.Owner = Application.Current.MainWindow;
pleaseWaitView.DataContext = pleaseWaitViewModel;
DoSomething = new ActionCommand<object>(DoSomethingImpl);
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pleaseWaitView.Close();
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Some work
Thread.Sleep(5000);
}
private void DoSomethingImpl(object parameter)
{
pleaseWaitView.ShowDialog();
}
}
如何解决这个问题?我在 20 分钟内完成了我想要的代码隐藏,我想尝试 MVVM 模式,我需要几个小时来解决简单的问题。
我正在使用 EventAggregator 寻找一些解决方案,但这需要使用像 Prism、Caliburn.Micro 这样的框架。所以我得到了虚拟机和 View 之间的某种通信。
最佳答案
您可以将包含所需方法的接口(interface)传递给 MainViewModel
interface IMainView
{
void Init(PleaseWaitViewModel viewModel);
void ShowDialog();
void Close();
}
public class MainViewModel
{
private IMainView _view;
public MainViewModel(IMainView view)
{
_view = view;
backgroundWorker = new BackgroundWorker() { WorkerSupportsCancellation = true };
backgroundWorker.DoWork += BackgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted +=
BackgroundWorker_RunWorkerCompleted;
var pleaseWaitViewModel = new PleaseWaitViewModel(backgroundWorker);
_view.Init(pleaseWaitViewModel);
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_view.Close();
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Some work
Thread.Sleep(5000);
}
private void DoSomethingImpl(object parameter)
{
_view.ShowDialog();
}
}
关于c# - 带有所有者的 MVVM showDialog 并在后台工作人员完成时关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49599756/