WPF MenuItem.IsChecked 绑定不起作用
WPF MenuItem.IsChecked binding not working
我有一个简单的菜单,希望绑定 MenuItems 的 IsChecked 属性,以便我以后可以在代码隐藏中操作它们。我在 属性 的 getter 和 setter 中设置了一个断点,但它们从未被击中。
我搜索了其他问题,none 已经阐明了我的问题。我创建了一个骨架项目来展示我所看到的。
MainWindow.xaml:
<Window x:Class="POC_BindingMenuItemIsChecked.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:POC_BindingMenuItemIsChecked"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MainWindowViewModel x:Key="mainWindowViewModel"/>
</Window.Resources>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="Choice">
<MenuItem Header="Alpha"
IsCheckable="True"
Checked="MenuItemAlpha_Checked"
IsChecked="{Binding AlphaIsRecording, Mode=TwoWay}"/>
<MenuItem Header="Bravo"
IsCheckable="True"
Checked="MenuItemBravo_Checked"
IsChecked="{Binding
Source={StaticResource mainWindowViewModel},
Path=BravoIsRecording,
Mode=TwoWay}"/>
<MenuItem Header="Charlie"
IsCheckable="True"
Checked="MenuItemCharlie_Checked"
IsChecked="{Binding CharlieIsRecording, Mode=TwoWay}"/>
</MenuItem>
</Menu>
</DockPanel>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
private MainWindowViewModel _MainWindowViewModel = null;
public MainWindow()
{
InitializeComponent();
// get a reference to the binding sources so we can set the properties
_MainWindowViewModel = new MainWindowViewModel();
this.DataContext = _MainWindowViewModel;
}
private void MenuItemAlpha_Checked(object sender, RoutedEventArgs e)
{
//no-op yet
}
private void MenuItemBravo_Checked(object sender, RoutedEventArgs e)
{
//no-op yet
}
private void MenuItemCharlie_Checked(object sender, RoutedEventArgs e)
{
//no-op yet
}
}
MainWindowViewModel.cs:
class MainWindowViewModel : DependencyObject
{
// Alpha
public static PropertyMetadata AlphaIsRecordingPropertyMetadata
= new PropertyMetadata(null);
public static DependencyProperty AlphaIsRecordingProperty
= DependencyProperty.Register(
"AlphaIsRecording",
typeof(bool),
typeof(MainWindowViewModel),
AlphaIsRecordingPropertyMetadata);
public bool AlphaIsRecording
{
get { return (bool)GetValue(AlphaIsRecordingProperty); }
set { SetValue(AlphaIsRecordingProperty, value); }
}
// Bravo
public static PropertyMetadata BravoIsRecordingPropertyMetadata
= new PropertyMetadata(null);
public static DependencyProperty BravoIsRecordingProperty
= DependencyProperty.Register(
"BravoIsRecording",
typeof(bool),
typeof(MainWindowViewModel),
BravoIsRecordingPropertyMetadata);
public bool BravoIsRecording
{
get { return (bool)GetValue(BravoIsRecordingProperty); }
set { SetValue(BravoIsRecordingProperty, value); }
}
// Charlie
public static PropertyMetadata CharlieIsRecordingPropertyMetadata
= new PropertyMetadata(null);
public static DependencyProperty CharlieIsRecordingProperty
= DependencyProperty.Register(
"CharlieIsRecording",
typeof(bool),
typeof(MainWindowViewModel),
CharlieIsRecordingPropertyMetadata);
public bool CharlieIsRecording
{
get { return (bool)GetValue(CharlieIsRecordingProperty); }
set { SetValue(CharlieIsRecordingProperty, value); }
}
}
编辑:
由于 mm8 提供的解决方案(POCO 而不是 Dependency),我修改了解决方案。它现在作为一组三个 MenuItem 充当单选按钮。代码如下:
MainWindow.xaml:
<Window x:Class="POC_BindingMenuItemIsChecked.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:POC_BindingMenuItemIsChecked"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MainWindowViewModel x:Key="mainWindowViewModel"/>
</Window.Resources>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="Choice">
<MenuItem Header="Alpha"
IsCheckable="True"
Checked="MenuItemAlpha_Checked"
IsChecked="{Binding AlphaIsRecording, Mode=TwoWay}"/>
<MenuItem Header="Bravo"
IsCheckable="True"
Checked="MenuItemBravo_Checked"
IsChecked="{Binding BravoIsRecording, Mode=TwoWay}"/>
<MenuItem Header="Charlie"
IsCheckable="True"
Checked="MenuItemCharlie_Checked"
IsChecked="{Binding CharlieIsRecording, Mode=TwoWay}"/>
</MenuItem>
</Menu>
</DockPanel>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
private MainWindowViewModel _mainWindowViewModel = null;
public MainWindow()
{
InitializeComponent();
// get a reference to the binding sources so we can set the properties
_mainWindowViewModel = new MainWindowViewModel();
this.DataContext = _mainWindowViewModel;
}
private void MenuItemAlpha_Checked(object sender, RoutedEventArgs e)
{
_mainWindowViewModel.BravoIsRecording = false;
_mainWindowViewModel.CharlieIsRecording = false;
}
private void MenuItemBravo_Checked(object sender, RoutedEventArgs e)
{
_mainWindowViewModel.AlphaIsRecording = false;
_mainWindowViewModel.CharlieIsRecording = false;
}
private void MenuItemCharlie_Checked(object sender, RoutedEventArgs e)
{
_mainWindowViewModel.AlphaIsRecording = false;
_mainWindowViewModel.BravoIsRecording = false;
}
}
ViewModelBase.cs:
class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
MainWindowViewModel.cs:
class MainWindowViewModel : ViewModelBase
{
private bool _alphaIsRecording = false;
private bool _bravoIsRecording = false;
private bool _charlieIsRecording = false;
// Alpha
public bool AlphaIsRecording
{
get { return _alphaIsRecording; }
set
{
_alphaIsRecording = value;
OnPropertyChanged("AlphaIsRecording");
}
}
// Bravo
public bool BravoIsRecording
{
get { return _bravoIsRecording; }
set
{
_bravoIsRecording = value;
OnPropertyChanged("BravoIsRecording");
}
}
// Charlie
public bool CharlieIsRecording
{
get { return _charlieIsRecording; }
set
{
_charlieIsRecording = value;
OnPropertyChanged("CharlieIsRecording");
}
}
}
您正在绑定 AlphaIsChecked
和 BravoIsChecked
但我没有看到任何此类属性?尝试绑定到 BravoIsRecording
:
<MenuItem Header="Bravo"
IsCheckable="True"
Checked="MenuItemBravo_Checked"
IsChecked="{Binding
Source={StaticResource mainWindowViewModel},
Path=BravoIsRecording,
Mode=TwoWay}"/>
此外,视图模型通常不会从 DependencyObject
继承并定义依赖属性。将您的属性转换为普通的 CLR 属性并在 BravoIsRecording
的 setter 中放置一个断点,当您检查 CheckBox
.
时它应该被击中
我有一个简单的菜单,希望绑定 MenuItems 的 IsChecked 属性,以便我以后可以在代码隐藏中操作它们。我在 属性 的 getter 和 setter 中设置了一个断点,但它们从未被击中。
我搜索了其他问题,none 已经阐明了我的问题。我创建了一个骨架项目来展示我所看到的。
MainWindow.xaml:
<Window x:Class="POC_BindingMenuItemIsChecked.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:POC_BindingMenuItemIsChecked"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MainWindowViewModel x:Key="mainWindowViewModel"/>
</Window.Resources>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="Choice">
<MenuItem Header="Alpha"
IsCheckable="True"
Checked="MenuItemAlpha_Checked"
IsChecked="{Binding AlphaIsRecording, Mode=TwoWay}"/>
<MenuItem Header="Bravo"
IsCheckable="True"
Checked="MenuItemBravo_Checked"
IsChecked="{Binding
Source={StaticResource mainWindowViewModel},
Path=BravoIsRecording,
Mode=TwoWay}"/>
<MenuItem Header="Charlie"
IsCheckable="True"
Checked="MenuItemCharlie_Checked"
IsChecked="{Binding CharlieIsRecording, Mode=TwoWay}"/>
</MenuItem>
</Menu>
</DockPanel>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
private MainWindowViewModel _MainWindowViewModel = null;
public MainWindow()
{
InitializeComponent();
// get a reference to the binding sources so we can set the properties
_MainWindowViewModel = new MainWindowViewModel();
this.DataContext = _MainWindowViewModel;
}
private void MenuItemAlpha_Checked(object sender, RoutedEventArgs e)
{
//no-op yet
}
private void MenuItemBravo_Checked(object sender, RoutedEventArgs e)
{
//no-op yet
}
private void MenuItemCharlie_Checked(object sender, RoutedEventArgs e)
{
//no-op yet
}
}
MainWindowViewModel.cs:
class MainWindowViewModel : DependencyObject
{
// Alpha
public static PropertyMetadata AlphaIsRecordingPropertyMetadata
= new PropertyMetadata(null);
public static DependencyProperty AlphaIsRecordingProperty
= DependencyProperty.Register(
"AlphaIsRecording",
typeof(bool),
typeof(MainWindowViewModel),
AlphaIsRecordingPropertyMetadata);
public bool AlphaIsRecording
{
get { return (bool)GetValue(AlphaIsRecordingProperty); }
set { SetValue(AlphaIsRecordingProperty, value); }
}
// Bravo
public static PropertyMetadata BravoIsRecordingPropertyMetadata
= new PropertyMetadata(null);
public static DependencyProperty BravoIsRecordingProperty
= DependencyProperty.Register(
"BravoIsRecording",
typeof(bool),
typeof(MainWindowViewModel),
BravoIsRecordingPropertyMetadata);
public bool BravoIsRecording
{
get { return (bool)GetValue(BravoIsRecordingProperty); }
set { SetValue(BravoIsRecordingProperty, value); }
}
// Charlie
public static PropertyMetadata CharlieIsRecordingPropertyMetadata
= new PropertyMetadata(null);
public static DependencyProperty CharlieIsRecordingProperty
= DependencyProperty.Register(
"CharlieIsRecording",
typeof(bool),
typeof(MainWindowViewModel),
CharlieIsRecordingPropertyMetadata);
public bool CharlieIsRecording
{
get { return (bool)GetValue(CharlieIsRecordingProperty); }
set { SetValue(CharlieIsRecordingProperty, value); }
}
}
编辑:
由于 mm8 提供的解决方案(POCO 而不是 Dependency),我修改了解决方案。它现在作为一组三个 MenuItem 充当单选按钮。代码如下:
MainWindow.xaml:
<Window x:Class="POC_BindingMenuItemIsChecked.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:POC_BindingMenuItemIsChecked"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MainWindowViewModel x:Key="mainWindowViewModel"/>
</Window.Resources>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="Choice">
<MenuItem Header="Alpha"
IsCheckable="True"
Checked="MenuItemAlpha_Checked"
IsChecked="{Binding AlphaIsRecording, Mode=TwoWay}"/>
<MenuItem Header="Bravo"
IsCheckable="True"
Checked="MenuItemBravo_Checked"
IsChecked="{Binding BravoIsRecording, Mode=TwoWay}"/>
<MenuItem Header="Charlie"
IsCheckable="True"
Checked="MenuItemCharlie_Checked"
IsChecked="{Binding CharlieIsRecording, Mode=TwoWay}"/>
</MenuItem>
</Menu>
</DockPanel>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
private MainWindowViewModel _mainWindowViewModel = null;
public MainWindow()
{
InitializeComponent();
// get a reference to the binding sources so we can set the properties
_mainWindowViewModel = new MainWindowViewModel();
this.DataContext = _mainWindowViewModel;
}
private void MenuItemAlpha_Checked(object sender, RoutedEventArgs e)
{
_mainWindowViewModel.BravoIsRecording = false;
_mainWindowViewModel.CharlieIsRecording = false;
}
private void MenuItemBravo_Checked(object sender, RoutedEventArgs e)
{
_mainWindowViewModel.AlphaIsRecording = false;
_mainWindowViewModel.CharlieIsRecording = false;
}
private void MenuItemCharlie_Checked(object sender, RoutedEventArgs e)
{
_mainWindowViewModel.AlphaIsRecording = false;
_mainWindowViewModel.BravoIsRecording = false;
}
}
ViewModelBase.cs:
class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
MainWindowViewModel.cs:
class MainWindowViewModel : ViewModelBase
{
private bool _alphaIsRecording = false;
private bool _bravoIsRecording = false;
private bool _charlieIsRecording = false;
// Alpha
public bool AlphaIsRecording
{
get { return _alphaIsRecording; }
set
{
_alphaIsRecording = value;
OnPropertyChanged("AlphaIsRecording");
}
}
// Bravo
public bool BravoIsRecording
{
get { return _bravoIsRecording; }
set
{
_bravoIsRecording = value;
OnPropertyChanged("BravoIsRecording");
}
}
// Charlie
public bool CharlieIsRecording
{
get { return _charlieIsRecording; }
set
{
_charlieIsRecording = value;
OnPropertyChanged("CharlieIsRecording");
}
}
}
您正在绑定 AlphaIsChecked
和 BravoIsChecked
但我没有看到任何此类属性?尝试绑定到 BravoIsRecording
:
<MenuItem Header="Bravo"
IsCheckable="True"
Checked="MenuItemBravo_Checked"
IsChecked="{Binding
Source={StaticResource mainWindowViewModel},
Path=BravoIsRecording,
Mode=TwoWay}"/>
此外,视图模型通常不会从 DependencyObject
继承并定义依赖属性。将您的属性转换为普通的 CLR 属性并在 BravoIsRecording
的 setter 中放置一个断点,当您检查 CheckBox
.