动态创建控件时,RadioButton 上的已检查事件命令绑定不起作用
Checked event command binding on RadioButton doesn't work when the control is dynamically created
我有 3 个 RadioButton
控件,我在我定义的自定义 class 和 ItemsControl
的帮助下动态添加到我的 WPF
程序中。我的习惯 class 很简单;它有两个属性,一个是标识符,另一个是 bool
来表示 Checked/Unchecked
状态。
public class RadioButtonItem
{
public string ItemName { get; set; }
public bool IsChecked { get; set; }
}
我正在使用 MVVMLight
,并且 ViewModel
和 DataContext
等都已正确设置。
在 MainWindow
中,我添加了 RadioButton
控件,如下所示:
<Grid x:Name="LayoutRoot">
<ItemsControl ItemsSource="{Binding Path=RadioButtons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding ItemName}"
IsChecked="{Binding IsChecked}"
Margin="12" GroupName="ABC">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding RadioButtonCheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
注意 i
是 Interactivity
命名空间:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
现在在我的 ViewModel
中,我创建了一个 RadioButtonItem
实例的列表,并且在加载时它在 XAML
端创建了 3 个 RadioButton
控件就好了,正如我所料。然后使用 MVVMLight
命令 RelayCommand
,我将 Checked
事件连接到 RadioButtonCheckedCommand
命令,后者又应该调用 RadioButtonChecked()
私有方法。
public class MainViewModel : ViewModelBase
{
private List<RadioButtonItem> _radioButtons;
public List<RadioButtonItem> RadioButtons
{
get => _radioButtons;
set { _radioButtons = value; RaisePropertyChanged(); }
}
public RelayCommand RadioButtonCheckedCommand { get; private set; }
public MainViewModel()
{
RadioButtons = new List<RadioButtonItem>
{
new RadioButtonItem() { ItemName = "A", IsChecked = false },
new RadioButtonItem() { ItemName = "B", IsChecked = false },
new RadioButtonItem() { ItemName = "C", IsChecked = false },
};
RadioButtonCheckedCommand = new RelayCommand(RadioButtonChecked);
}
private void RadioButtonChecked()
{
}
}
但是,当我 运行 程序时,它不会调用上述事件。它也没有给我任何错误。如何让事件在这样动态创建的控件中工作?
为了验证我的命令绑定等是否有效,我还在 window 上创建了三个静态 RadioButton
控件,如下所示,并将它们附加到同一个命令,它们在 Checked
事件。
<StackPanel Grid.Row="1" HorizontalAlignment="Center">
<RadioButton Content="X" Margin="12">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding RadioButtonCheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
<RadioButton Content="Y" Margin="12">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding RadioButtonCheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
<RadioButton Content="Z" Margin="12">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding RadioButtonCheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
</StackPanel>
在 ItemsControl
中,绑定到 RadioButtonCheckedCommand 正在尝试根据项目解析它 - RadioButtonItem
实例
但是命令是在 MainViewModel 中定义的。它在 StackPanel 中工作,因为没有绑定到 RadioButtonItems。
解决方案是绑定到ItemsControl.DataContext(与Grid.DataContext相同):
<i:InvokeCommandAction Command="{Binding Path=DataContext.RadioButtonCheckedCommand, ElementName=LayoutRoot}"/>
之前的回答很完美。如果您不想使用 elemnt name "LayoutRoot".
,这只是另一种解决方案
<i:InvokeCommandAction Command="{Binding Path=DataContext.RadioButtonCheckedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}"/>
我有 3 个 RadioButton
控件,我在我定义的自定义 class 和 ItemsControl
的帮助下动态添加到我的 WPF
程序中。我的习惯 class 很简单;它有两个属性,一个是标识符,另一个是 bool
来表示 Checked/Unchecked
状态。
public class RadioButtonItem
{
public string ItemName { get; set; }
public bool IsChecked { get; set; }
}
我正在使用 MVVMLight
,并且 ViewModel
和 DataContext
等都已正确设置。
在 MainWindow
中,我添加了 RadioButton
控件,如下所示:
<Grid x:Name="LayoutRoot">
<ItemsControl ItemsSource="{Binding Path=RadioButtons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding ItemName}"
IsChecked="{Binding IsChecked}"
Margin="12" GroupName="ABC">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding RadioButtonCheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
注意 i
是 Interactivity
命名空间:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
现在在我的 ViewModel
中,我创建了一个 RadioButtonItem
实例的列表,并且在加载时它在 XAML
端创建了 3 个 RadioButton
控件就好了,正如我所料。然后使用 MVVMLight
命令 RelayCommand
,我将 Checked
事件连接到 RadioButtonCheckedCommand
命令,后者又应该调用 RadioButtonChecked()
私有方法。
public class MainViewModel : ViewModelBase
{
private List<RadioButtonItem> _radioButtons;
public List<RadioButtonItem> RadioButtons
{
get => _radioButtons;
set { _radioButtons = value; RaisePropertyChanged(); }
}
public RelayCommand RadioButtonCheckedCommand { get; private set; }
public MainViewModel()
{
RadioButtons = new List<RadioButtonItem>
{
new RadioButtonItem() { ItemName = "A", IsChecked = false },
new RadioButtonItem() { ItemName = "B", IsChecked = false },
new RadioButtonItem() { ItemName = "C", IsChecked = false },
};
RadioButtonCheckedCommand = new RelayCommand(RadioButtonChecked);
}
private void RadioButtonChecked()
{
}
}
但是,当我 运行 程序时,它不会调用上述事件。它也没有给我任何错误。如何让事件在这样动态创建的控件中工作?
为了验证我的命令绑定等是否有效,我还在 window 上创建了三个静态 RadioButton
控件,如下所示,并将它们附加到同一个命令,它们在 Checked
事件。
<StackPanel Grid.Row="1" HorizontalAlignment="Center">
<RadioButton Content="X" Margin="12">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding RadioButtonCheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
<RadioButton Content="Y" Margin="12">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding RadioButtonCheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
<RadioButton Content="Z" Margin="12">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding RadioButtonCheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
</StackPanel>
在 ItemsControl
中,绑定到 RadioButtonCheckedCommand 正在尝试根据项目解析它 - RadioButtonItem
实例
但是命令是在 MainViewModel 中定义的。它在 StackPanel 中工作,因为没有绑定到 RadioButtonItems。
解决方案是绑定到ItemsControl.DataContext(与Grid.DataContext相同):
<i:InvokeCommandAction Command="{Binding Path=DataContext.RadioButtonCheckedCommand, ElementName=LayoutRoot}"/>
之前的回答很完美。如果您不想使用 elemnt name "LayoutRoot".
,这只是另一种解决方案<i:InvokeCommandAction Command="{Binding Path=DataContext.RadioButtonCheckedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}"/>