我有一个WPF应用程序,它调用MessageBox.Show()早在视图模型 (以检查用户是否真的要删除)。 其实,这工作 ,但违背因为视图模型MVVM的粮食不应该明确地确定在查看发生了什么。
所以,现在我想我怎样才能最好的在我的MVVM应用,期权执行MessageBox.Show()功能 :
我有一个消息与文本“你确定......?” 随着两个按钮是和否都在我的XAML边框,所以它是基于ViewModelProperty称为AreYourSureDialogueBoxIsVisible崩溃/可见光,然后当我需要这个对话框中,分配AreYourSureDialogueBoxIsVisible为“true创建模板触发”,并通过处理的DelegateCommand两个按钮回到我的视图模型。
我也可以以某种方式尝试在XAML触发器来处理这一点,以便删除按钮实际上只是使一些Border元素出现在它的消息和按钮,和Yes按钮做的实际删除。
这两种解决方案似乎是曾经被认为是的代码MessageBox.Show几行太复杂 ()。
在哪些方面你有成功实施的对话盒在MVVM应用程序?
你提到的这两个,我宁愿选择#2。 页面上的删除按钮只是使“确认删除对话框”出现。 “确认删除对话框”,实际上揭开序幕删除。
已签出卡尔Shifflett的WPF的行当幻灯片和演示 ? 我知道他做这样的事情。 我会尽量记住。
编辑:查看演示#11 “MVVM数据有效性”(EditContactItemsControlSelectionViewModel.DeleteCommand)。 卡尔称从ViewModal一个弹出(什么!?:-)。 其实,我喜欢你的想法更好。 似乎更容易进行单元测试。
服务救援。 使用玛瑙 (声明,我是作者),这是一样简单:
public void Foo()
{
IDisplayMessage dm = this.View.GetService<IDisplayMessage>();
dm.Show("Hello, world!");
}
在运行的应用程序,这将间接调用MessageBox.Show(“你好,世界!”)。 测试时,该IDisplayMessage服务可以被嘲笑,并提供给视图模型做你想要在测试过程中要完成什么都。
现在就院长粉笔的回答展开他的链接是过时的:
在App.xaml.cs文件中,我们挂钩的确认对话框到视图模型。
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var confirm = (Func<string, string, bool>)((msg, capt) => MessageBox.Show(msg, capt, MessageBoxButton.YesNo) == MessageBoxResult.Yes);
var window = new MainWindowView();
var viewModel = new MainWindowViewModel(confirm);
window.DataContext = viewModel;
...
}
在视图(MainWindowView.xaml),我们有一个按钮,在视图模型调用命令
<Button Command="{Binding Path=DeleteCommand}" />
该视图模型(MainWindowViewModel.cs)使用委托命令显示“你确定?” 对话和执行的操作。 在这个例子中它是一个SimpleCommand
类似于此 ,但ICommand的任何执行应该做的。
private readonly Func<string, string, bool> _confirm;
//constructor
public MainWindowViewModel(Func<string, string, bool> confirm)
{
_confirm = confirm;
...
}
#region Delete Command
private SimpleCommand _deleteCommand;
public ICommand DeleteCommand
{
get { return _deleteCommand ?? (_deleteCommand = new SimpleCommand(ExecuteDeleteCommand, CanExecuteDeleteCommand)); }
}
public bool CanExecuteDeleteCommand()
{
//put your logic here whether to allow deletes
return true;
}
public void ExecuteDeleteCommand()
{
bool doDelete =_confirm("Are you sure?", "Confirm Delete");
if (doDelete)
{
//delete from database
...
}
}
#endregion
我只是创造出被注入到虚拟机的接口(IMessageDisplay或类似),它具有像一个MessageBox(ShowMessage()等)的方法。 您可以实现使用标准的消息框,或一些更具体的WPF(我用CodePlex上这个有些家伙叫Prajeesh)。
一切都这样真实分离和测试。
关于引发一个事件像什么"MessageBoxRequested"
在查看的代码隐藏处理(反正它是只查看代码,所以我不认为具有在此代码隐藏代码的任何问题)。
我做了一个简单的MessageBox包装控件为我们在纯MVVM解决方案中使用,并仍允许单元测试能力。 细节是在我的博客http://geekswithblogs.net/mukapu/archive/2010/03/12/user-prompts-messagebox-with-mvvm.aspx
杯
我实现了侦听来自视图模型消息的行为。 它是基于洛朗比尼翁的解决方案,但由于它不使用的代码背后,是更多的可重复使用的,我认为这是更优雅。
看看这里
WPF和Silverlight的提示消息框
MVVM支持
http://slwpfmessagebox.codeplex.com/
万一别人还在读书不满意:
我只是想办理“通知”提示消息类型(即我不关心DialogResult
),但我有我读过大多数解决方案的问题的是,他们似乎间接地迫使你选择你的视图实现(也就是说,目前我有一个MessageBox.Show
,但如果我决定以后只用一个隐藏的面板直接在我看来,知名度,不会与网非常漂亮拨弄INotification
到视图模型传递接口)。
于是,我去了快速和肮脏的:
该视图模型有一个string NotificationMessage
财产,以通知变化PropertyChanged
。
查看订阅PropertyChanged
,如果它看到NotificationMessage
财产通过来了,不为所欲为。
OK,所以这意味着该视图代码后面,名称PropertyChanged
是硬编码,但在XAML将它硬编码的反正。 这也意味着我避免像所有转换器可视性和属性的东西,说通知是否仍然可见或不可见。
(诚然,这仅仅是,我还没有考虑了很久我怎么可能要扩展它在有限的用例(发射后不管)。)
我只想从VM扔掉它。 我不想不得不使用别人的服务或写我自己只是抛出一个消息。
我最近遇到这个问题,我曾与一些完全MVVM投诉消息框机制,以替代的ViewModels的MessageBox.Show来了。
要做到这一点我用InteractionRequest<Notification>
和InteractionRequest<Confirmation>
与互动触发沿,写我自己的看法消息框。
我已经实现了发布在这里
有关于这一主题,从创建一个自定义类使用第三方库不同,所以很多答案。 我会说,如果你想与漂亮的视觉效果很酷的弹出窗口使用第三方库。
但如果你只是想在这里使用微软的常规消息框,您的WPF应用程序是一个MVVM /单元测试友好的实现:
起初我以为我只是从消息框继承与接口包起来,但我不能因为没有一个公共的构造函数消息框,所以这里是“易”的解决方案:
在Visual Studio反编译消息框,你可以看到所有的方法重载,我检查哪些,我想,然后创建一个新的类,并添加方法,用一个接口和当当包裹吧! 现在你可以使用ninject的接口和类绑定,注入并使用最小起订量来的单元测试等
创建一个接口(只增加了一些重载的,因为我不需要他们全部):
public interface IMessageBox
{
/// <summary>Displays a message box that has a message, title bar caption, and button; and that returns a result.</summary>
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button);
/// <summary>Displays a message box that has a message, title bar caption, button, and icon; and that returns a result.</summary>
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);
/// <summary>Displays a message box that has a message and title bar caption; and that returns a result.</summary>
MessageBoxResult Show(string messageBoxText, string caption);
}
然后我们将继承它的类:
public class MessageBoxHelper : IMessageBox
{
/// <summary>Displays a message box that has a message, title bar caption, button, and icon; and that returns a result.</summary>
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button,
MessageBoxImage icon)
{
return MessageBox.Show(messageBoxText, caption, button, icon, MessageBoxResult.None,
MessageBoxOptions.None);
}
/// <summary>Displays a message box that has a message, title bar caption, and button; and that returns a result.</summary>
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
{
return MessageBox.Show(messageBoxText, caption, button, MessageBoxImage.None, MessageBoxResult.None,
MessageBoxOptions.None);
}
/// <summary>Displays a message box that has a message and title bar caption; and that returns a result.</summary>
public MessageBoxResult Show(string messageBoxText, string caption)
{
return MessageBox.Show(messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None,
MessageBoxResult.None, MessageBoxOptions.None);
}
/// <summary>Displays a message box that has a message and that returns a result.</summary>
public MessageBoxResult Show(string messageBoxText)
{
return MessageBox.Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None,
MessageBoxResult.None, MessageBoxOptions.None);
}
}
现在只要使用此注射时等和繁荣u有一个脆弱的抽象,它会做的伎俩......根据您将使用它这是罚款。 我的情况是一个简单的应用程序只是为了做几件事情,所以在工程的解决方案是没有意义的。 希望这可以帮助别人。
文章来源: How have you successfully implemented MessageBox.Show() functionality in MVVM?