我在视图模型中有一个附加到命令的按钮。此按钮删除列表视图中当前选择的行,因此我希望在继续之前显示确认消息框。用户单击确定按钮(在消息框中)然后执行命令,否则,如果用户单击取消按钮命令附加未被调用。可能吗?如果是这样的话?
<Button Name="btnDelete" Command="{Binding DeleteRowsCommand}"/>
另一种可能性是通过附加到视图中放置的自定义消息框的属性在单击和视图模型中调用命令,以在属性值为true时使此自定义消息框可见。但是,我怎样才能回到视图模型按下“确定”或“取消”按钮?
只需使用MessageBox
;)
在路由到DeleteRowsCommand
的方法中使用此
var result = MessageBox.Show("message", "caption", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
//your logic
}
有关更多信息,请查看MessageBox Class。
在执行命令之前,视图模型通常不需要知道用户存在问题。如果是这种情况,您可以创建非常简单的自定义按钮类以显示消息框,如果用户单击是,则执行命令(或执行任何操作)。
public class YesNoButton : Button
{
public string Question { get; set; }
protected override void OnClick()
{
if (string.IsNullOrWhiteSpace(Question))
base.OnClick();
var messageBoxResult = MessageBox.Show(Question, "Confirmation", MessageBoxButton.YesNo);
if (messageBoxResult == MessageBoxResult.Yes)
base.OnClick();
}
}
在XAML中,您可以使用如下按钮:
<components:YesNoButton Content="Delete rows" Command="{Binding DeleteRowsCommand}" Question="Do you really want to delete rows?" />
其中一种可能(在我看来最干净)的方法是实现像DialogService这样的服务,将其注入ViewModel并在执行命令时调用它。通过这样做,您可以解耦视图和应用程序逻辑,以便ViewModel完全不知道实际显示对话框的方式,并将所有工作委托给服务。这是一个例子。
首先,您创建一个对话框服务,处理显示对话框并返回结果的所有工作:
public interface IDialogService
{
bool ConfirmDialog(string message);
}
public bool ConfirmDialog(string message)
{
MessageBoxResult result = MessageBox.Show(message, "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question);
return result == MessageBoxResult.Yes ? true : false;
}
然后,让ViewModel依赖于该服务,并在ViewModel中使用inject:
public class MyViewModel : ViewModelBase
{
private readonly IDialogService _dialogService;
public MyViewModel(IDialogService dialogService)
{
_dialogService = dialogService;
}
}
最后,在您的命令中,您可以在命令中调用服务,以检查用户是否完全确定是否要删除记录:
public Command DeleteRecordsCommand
{
get
{
if (_deleteRecordsCommand == null)
{
_deleteRecordsCommand = new Command(
() =>
{
if (_dialogService.ConfirmDialog("Delete records?"))
{
// delete records
}
}
);
}
return _deleteRecordsCommand;
}
}