假设以下简化方案:
//Model:
public class SessionModel: ObservableObject {
public bool IsChecked; // IPropertyChanged is implemented
}
//ViewModel:
public class SessionViewModel: ViewModel {
public IDialogService DialogService {get; set;}
public ObservableCollection<SessionModel> Items; // IPropertyChanged is implemented
public async Task DownloadFromUsbDevice() {
await = Task.Run(() => DownloadFromUsbDevice());
}
private void DownloadFromUsbDevice() {
// Get all checked items. If result is empty, show a message. If an error occurs, show error message
}
}
// Simple IDialogService...
public interface IDialogService
{
void ShowMessage(string message);
}
我的第一个想法是,ViewModel的View应该实现这个......这是可能的,但是我需要手动将View分配给views构造函数中的ViewModel属性......
//DialogService:
public class MainWindow: Window, IDialogService
{
public MainWindow()
{
ViewModel.DialogService = this;
}
public void ShowMessage(string message)
{
Xceed.Wpf.Toolkit.MessageBox.Show(this, message, string.Empty, MessageBoxButton.OK, MessageBoxImage.Error);
}
}
然后我读到大多数这些服务似乎是独立实现的......但是对于模态对话框和线程安全访问,我需要目标视图的Window / Dispatcher ...所以我必须注册接口及其对SimpleIoc的实现。然后我必须使用特定于此View / ViewModel的键并在视图构造函数中创建实例并分配Window。
//DialogService:
public class StandaloneDialogService: IDialogService
{
public Window Parent { get; set; }
public void ShowMessage(string message)
{
Xceed.Wpf.Toolkit.MessageBox.Show(Parent, message, string.Empty, MessageBoxButton.OK, MessageBoxImage.Error);
}
}
//ServiceLocator:
public class Locator
{
public Locator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<IDialogService, StandaloneDialogService>();
SimpleIoc.Default.Register<SessionViewModel>();
}
public SessionViewModel Session => SimpleIoc.Default.GetInstance<Session>();
}
//View:
public class MainWindow: Window
{
public MainWindow()
{
SimpleIoc.Default.GetInstance<IDialogService>("x").Parent = this;
}
}
//ViewModel:
public class SessionViewModel: ViewModel {
public IDialogService DialogService => SimpleIoc.Default.GetInstance<IDialogService>("x");
public ObservableCollection<SessionModel> Items; // IPropertyChanged is implemented
public async Task DownloadFromUsbDevice()
{
await = Task.Run(() => DownloadFromUsbDevice());
}
private void DownloadFromUsbDevice()
{
// Get all checked items. If result is empty, show a message. If an error occurs, show error message
}
}
长话短说......这两个中的一个是从ViewModel的worker-function显示(模态/非模态)消息的正确方法吗?有更好的解决方案吗?还是我完全错了?