我有一个ViewModel需要在按钮点击时显示一个模态窗口(使用ShowDialog()
)。 ViewModel捕获click命令,但我不想在ViewModel中执行window.ShowDialog()
。我知道MVVM Light中有一个DialogMessage
,但它用于显示消息框,而不是WPF模式窗口。
关于如何做到这一点的任何想法?
答案 0 :(得分:20)
您应该使用Messenger
课程。在View
上注册要显示的消息窗口,然后在需要显示它时调用Send
类的Messenger
方法。
您可以这样做:
//do this in code behind file of your View
Messenger.Default.Register<string>(this, ShowWindow);
private void ShowWindow(string message)
{
// your logic here
}
// In the ViewModel
Messenger.Default.Send(“Some text”);
答案 1 :(得分:11)
这是我用于MVVM-Light Toolkit的自定义对话框。
首先,在应用程序的某处定义这四个类。 MessageBase类是工具包的一部分。
public class ShowChildWindowMessage : MessageBase { }
public class HideChildWindowMessage : MessageBase { }
public class DisplaySomeContentMessage : MessageBase { }
public class DisplaySomeOtherContentMessage : MessageBase { }
其次,你需要一个“子”窗口控件。使用以下内容创建XAML文件:
<Window x:Class="ChildWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding Path=ChildWindowBinding, Source={StaticResource Locator}}"
Title="{Binding Path=CurrentContent.DisplayName}"
MinWidth="300" MinHeight="125" SizeToContent="WidthAndHeight"
ShowInTaskbar="False" WindowState="Normal" ResizeMode="NoResize"
WindowStartupLocation="CenterOwner" SnapsToDevicePixels="True">
<Grid>
<ContentPresenter Content="{Binding Path=CurrentContent}" />
</Grid>
然后将以下内容添加到此XAML文件的代码隐藏中:
public partial class ChildWindowView : Window
{
public ChildWindowView(Window owner)
{
InitializeComponent();
Owner = owner;
Closing += (s, e) =>
{
// window reused so just hide
e.Cancel = true;
Messenger.Default.Send(new HideChildWindowMessage());
};
}
}
第三,将以下内容添加到MainWindow.xaml文件的代码隐藏中:
public partial class MainWindowView : Window
{
private ChildWindowView m_childWindowView;
public MainWindowView()
{
InitializeComponent();
Closing += (s, e) => ViewModelLocator.CleanUp();
Loaded += (s, e) =>
{
m_childWindowView = new ChildWindowView(this);
};
Messenger.Default.Register<ShowChildWindowMessage>(this, (msg) => m_childWindowView.ShowDialog());
Messenger.Default.Register<HideChildWindowMessage>(this, (msg) => m_childWindowView.Hide());
}
}
第四,定义以下视图模型:
public class ChildWindowVM : ViewModelBase
{
private ViewModelBase m_currentContent;
public ViewModelBase CurrentContent
{
get { return m_currentContent; }
set
{
m_currentContent = value;
RaisePropertyChanged("CurrentContent");
if (m_currentContent != null)
{
Messenger.Default.Send(new ShowChildWindowMessage());
}
}
}
public ChildWindowVM()
{
Messenger.Default.Register<DisplaySomeContentMessage>(this, (msg) => CurrentContent = ViewModelLocator.SomeContentVm);
Messenger.Default.Register<DisplaySomeOtherContentMessage>(this, (msg) => CurrentContent = ViewModelLocator.SomeOtherContentVm);
}
}
第五,您创建XAML文件并查看要在自定义对话框中显示的内容的模型。在此示例中,我的内容视图模型名为SomeContent和SomeOtherContent。当然,你可以用你想要的东西替换它们。
最后,为了实现这一点,您必须将以下内容添加到应用程序资源中,将内容视图模型绑定到各自的XAML文件:
<DataTemplate DataType="{x:Type viewmodels:SomeContentVM}">
<views:SomeContentView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:SomeOtherContentVM}">
<views:SomeOtherContentView/>
</DataTemplate>
现在,一旦完成所有这些设置,就可以很容易地添加可以在子窗口中显示的新内容(XAML和视图模型)。要显示内容,只需使用Messenger类调用相应的消息:
Messenger.Default.Send(new DisplaySomeContentMessage ());
如果我需要为您澄清这方面的任何部分,请告诉我。
答案 2 :(得分:0)
对于那些想要一个非常简单的解决方案并且没有-100%-clean-MVVM的人来说: 我想从主窗口打开一个连接对话框并执行以下操作
首先,我给了我的MainWindow一个名字:
<Window x:Name="MainWindow">
然后我在MainWindowViewModel中创建了一个Command:
public ICommand AddInterfaceCommand
{
get
{
return new RelayCommand<Window>((parentWindow) =>
{
var wizard = new ConnectionWizard();
wizard.Owner = parentWindow;
wizard.ShowDialog();
}
}
}
我将MainWindow上的Button绑定到Command并传递了窗口本身(对话框的父窗口):
<Button Command="{Binding AddInterfaceCommand}" CommandParameter="{Binding ElementName=MainWindow}">Add interface</Button>
就是这样。
唯一警告:从Dialog的Viewmodel获取返回值可能很困难。我不需要这个功能。
答案 3 :(得分:0)
您可以按如下方式定义接口及其实现。而且依赖于依赖注入容器,你必须做这样的事情。
NInjectKernel.Bind<IMessageBoxService>().To<MessageBoxService>();
您的ViewModel看起来像这样。
private IMessageBoxService _MBService;
public DropboxSettingsViewModel(IDropboxService dbService, IMessageBoxService mbService)
{
if (dbService == null)
throw new ArgumentNullException("IDropboxService is null");
_DropboxService = dbService;
if (mbService == null)
throw new ArgumentNullException("MessageBoxService is null");
_MBService = mbService;
}
您的点击命令执行方法如下。
private void ConfigureDropboxExecute(object obj)
{
_MBService.Show("Error Occured Authenticating dropbox", "Dropbox Authentication", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
}
public interface IMessageBoxService
{
MessageBoxResult Show(string messageBoxText);
MessageBoxResult Show(string messageBoxText, string caption);
MessageBoxResult Show(Window owner, string messageBoxText);
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button);
MessageBoxResult Show(Window owner, string messageBoxText, string caption);
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);
MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button);
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult);
MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options);
MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult);
MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options);
}
使用System.Windows;
public class MessageBoxService : IMessageBoxService
{
public MessageBoxResult Show(string messageBoxText)
{
return MessageBox.Show(messageBoxText);
}
public MessageBoxResult Show(Window owner, string messageBoxText)
{
return MessageBox.Show(owner, messageBoxText);
}
public MessageBoxResult Show(string messageBoxText, string caption)
{
return MessageBox.Show(messageBoxText, caption);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption)
{
return MessageBox.Show(owner, messageBoxText, caption);
}
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
{
return MessageBox.Show(messageBoxText, caption, button);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button)
{
return MessageBox.Show(owner, messageBoxText, caption, button);
}
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
{
return MessageBox.Show(messageBoxText, caption, button, icon);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
{
return MessageBox.Show(owner, messageBoxText, caption, button, icon);
}
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
{
return MessageBox.Show(messageBoxText, caption, button, icon, defaultResult);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
{
return MessageBox.Show(owner, messageBoxText, caption, button, icon, defaultResult);
}
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
{
return MessageBox.Show(messageBoxText, caption, button, icon, defaultResult, options);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
{
return MessageBox.Show(owner, messageBoxText, caption, button, icon, defaultResult, options);
}
}