在WPF中,我有一个绑定到设置的MenuItem,我希望每次用户单击它时都会弹出一个消息框。
<MenuItem IsCheckable="True" Header="MyConfig" IsChecked="{Binding Source={x:Static res:Settings.Default},
Path=MyConfigPath, Mode=TwoWay}"/>
执行此操作的最佳方法是什么(如果可能的话,没有隐藏代码(?
假设您要绑定到的Settings
类是扩展ApplicationSettingsBase
的自动生成的类,您可以将事件处理程序附加到SettingChanging
并在该事件处理程序中显示确认对话框,如果用户单击"取消",则需要设置e.Cancel = true
。
下面是一些伪代码,它假定首次显示 WPF 窗口时将调用WpfInit()
:
private void WpfInit()
{
Settings.Default.SettingChanging += Settings_SettingsChanging;
}
private void Settings_SettingsChanging(Object sender, SettingChangingEventArgs e) {
var dlgResult = MessageBox.Show("Are you sure?", "Please Confirm...", MessageBoxButton.YesNo);
if (dlgResult != MessageBoxResult.Yes) {
e.Cancel = true;
MessageBox.Show("Change cancelled");
}
}
笔记:
- 不要忘记在 WPF 窗体关闭时取消挂钩事件处理程序
Settings.Default.SettingChanging -= Settings_SettingsChanging;
- 我觉得这个代码后面会让任何碰巧阅读你的代码的人最清楚地知道你的意图是什么。当然,我相信有一种方法可以避免代码落后,但恕我直言,仅仅为了避免代码落后而避免代码落后并不总是代码可读性的最佳实践。
执行此操作的最佳方法是什么(如果可能的话,没有隐藏代码(?
那就是将MenuItem
的Command
属性绑定到视图模型的ICommand
属性,并在命令的Execute
方法中弹出消息框:
<MenuItem IsCheckable="True" Header="MyConfig" IsChecked="{Binding Source={x:Static res:Settings.Default},
Path=MyConfigPath, Mode=TwoWay}" Command="{Binding YourCommand}"/>
public DelegateCommand<object> YourCommand => new DelegateCommand<object>((arg) => MessageBox.Show(""));
在视图模型中调用阻塞MessageBox.Show
方法不是一个好主意,但那是另一回事了:https://blog.magnusmontin.net/2013/04/20/implement-a-confirmation-dialog-in-wpf-with-mvvm-and-prism/