将 CheckBox IsChecked 属性 绑定到 ListView 的 SelectedItems 属性
Binding the CheckBox IsChecked Property to SelectedItems Property of a ListView
我在 MVVM 数据绑定方面遇到困难。
在我的示例中,我有一个 ListView
填充的项目,其中包含 CheckBox
和一些其他内容。
<ListView
Background="#f0f0f0"
Grid.Row="1"
ItemsSource="{Binding ListViewCollection}"
SelectedItem="{Binding SelectedItem}"
IsSynchronizedWithCurrentItem="True"
BorderThickness="0"
Margin="5">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Tag="{Binding TheValue}" IsChecked="{Binding IsChecked}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding TheText}" Header="#Cell" />
<GridViewColumn DisplayMemberBinding="{Binding TheVoltage}" Header="U[V]" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
ListView
的 ItemSource
绑定到 ViewModel 中数据 class 的 ObservableCollection
,就像您在 MVVM 中所做的那样。
现在我想将每个列表视图项的 Checkbox.IsChecked
属性 连接到父级 ListView.SelectedItems
属性 以触发它。为什么?因为我要show/hide一系列的数据图。因此,如果选中第一行中的 CheckBox
,则显示图表 1。如果未选中第二行中的 CheckBox
,则隐藏图表 2,依此类推。像这样:
public ListViewItem SelectedItem
{
get { return mSelectedItem; }
set
{
if (mSelectedItem!= value)
{
mSelectedItem= value;
RaisePropertyChanged("SelectedItem");
if (SelectedItem.IsChecked == true)
{
OxyplotModel.Series[1].IsVisible = false;
OxyplotModel.InvalidatePlot(true);
}
}
}
}
要触发此 属性,您必须在 GUI 中单击两次。首先选中 CheckBox
,然后再次单击该行以触发并隐藏图表。但我想在点击 CheckBox
后立即触发 SelectedItems
属性。
至此,我给CheckBox
绑定了一个命令,并传递了一个参数来区分复选框。但正如我所说,我想使用 属性.
这是否可能或有更好的想法来解决我的问题?
所选项目将是绑定到项目源的项目类型。如果项目来源是列表意味着选择的项目将是学生。
据我了解,您的问题是由 CheckBox
从 ListViewItem
窃取焦点造成的。如果你想在 CheckBox
被点击时 select 项目,你可以使用当 ListViewItem
中的某些东西获得焦点时触发的动画,这会将 IsSelected
设置为 true
<ListView ...
ItemsSource="{Binding ListViewCollection}"
SelectedItem="{Binding SelectedItem}"
SelectionMode="Single">
<ListView.View>
<!-- removed -->
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<EventTrigger RoutedEvent="GotKeyboardFocus">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames BeginTime="0:0:0" Duration="0:0:0" Storyboard.TargetProperty="IsSelected">
<DiscreteBooleanKeyFrame Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
您还需要指定 SelectionMode="Single"
否则之前的项目将不会被取消selected
编辑
它向项目容器样式 (ListViewItem
) 添加了新的事件触发器,只要 GotKeyboardFocus
event occurs. It's bubbling event meaning it will bubble up the visual tree from any ListViewItem
child and finally reach ListViewItem
where it will trigger BooleanAnimationUsingKeyFrames
能够更改 Boolean
属性值的动画就会执行。在这种情况下,它不是真正的动画,因为它需要 0 秒,但它会将 IsSelected
属性(由 Storyboard.TargetProperty
指定)设置为 true
我想 post 使用 Command 和 CommandParameter 实现此解决方案的替代方法。
在您的 XAML 中将命令绑定到复选框。还将 CommandParameter 绑定到将传递给命令本身的值。请注意:因为 ListView 的 ItemSource 设置为 Observablecollection,所以您必须使用
更改为父 DataContext
Command="{Binding ElementName=NameOfListView,Path=DataContext.NameOfCommand}"
从 ViewModel DataContext 绑定命令。您也可以使用 Ancestor 来获取父数据上下文。
<ListView
Background="#f0f0f0"
Grid.Row="1"
ItemsSource="{Binding ListViewCollection}"
Name="ListView"
IsSynchronizedWithCurrentItem="True"
BorderThickness="0"
Margin="5">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}"
Command="{Binding ElementName=ListView,Path=DataContext.HideShowGraph}"
CommandParameter="{Binding TheValue, Mode=OneWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding TheText}" Header="#Cell" />
<GridViewColumn DisplayMemberBinding="{Binding TheVoltage}" Header="U[V]" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
然后在您的 ViewModel 中声明一个带参数的 RelayCommand 和相应的委托方法。
public class ViewModel : ViewModelBase
{
public ViewModel()
{
HideShowGraph = new RelayCommand<int>(foo => HideShowGraphExecute(foo));
}
public ICommand HideShowGraph { get; private set; }
private void HideShowGraphExecute(int foo)
{
//...evaluate foo
}
}
因此,如果选中 ListView 中的一个 Checkbox,则会调用 Command 并将 CommandParameter 的有界值(在此示例中 "TheValue")传递给委托方法 HideShowGraphExecute。使用此值,您可以区分复选框。
希望对您也有帮助!
我在 MVVM 数据绑定方面遇到困难。
在我的示例中,我有一个 ListView
填充的项目,其中包含 CheckBox
和一些其他内容。
<ListView
Background="#f0f0f0"
Grid.Row="1"
ItemsSource="{Binding ListViewCollection}"
SelectedItem="{Binding SelectedItem}"
IsSynchronizedWithCurrentItem="True"
BorderThickness="0"
Margin="5">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Tag="{Binding TheValue}" IsChecked="{Binding IsChecked}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding TheText}" Header="#Cell" />
<GridViewColumn DisplayMemberBinding="{Binding TheVoltage}" Header="U[V]" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
ListView
的 ItemSource
绑定到 ViewModel 中数据 class 的 ObservableCollection
,就像您在 MVVM 中所做的那样。
现在我想将每个列表视图项的 Checkbox.IsChecked
属性 连接到父级 ListView.SelectedItems
属性 以触发它。为什么?因为我要show/hide一系列的数据图。因此,如果选中第一行中的 CheckBox
,则显示图表 1。如果未选中第二行中的 CheckBox
,则隐藏图表 2,依此类推。像这样:
public ListViewItem SelectedItem
{
get { return mSelectedItem; }
set
{
if (mSelectedItem!= value)
{
mSelectedItem= value;
RaisePropertyChanged("SelectedItem");
if (SelectedItem.IsChecked == true)
{
OxyplotModel.Series[1].IsVisible = false;
OxyplotModel.InvalidatePlot(true);
}
}
}
}
要触发此 属性,您必须在 GUI 中单击两次。首先选中 CheckBox
,然后再次单击该行以触发并隐藏图表。但我想在点击 CheckBox
后立即触发 SelectedItems
属性。
至此,我给CheckBox
绑定了一个命令,并传递了一个参数来区分复选框。但正如我所说,我想使用 属性.
这是否可能或有更好的想法来解决我的问题?
所选项目将是绑定到项目源的项目类型。如果项目来源是列表意味着选择的项目将是学生。
据我了解,您的问题是由 CheckBox
从 ListViewItem
窃取焦点造成的。如果你想在 CheckBox
被点击时 select 项目,你可以使用当 ListViewItem
中的某些东西获得焦点时触发的动画,这会将 IsSelected
设置为 true
<ListView ...
ItemsSource="{Binding ListViewCollection}"
SelectedItem="{Binding SelectedItem}"
SelectionMode="Single">
<ListView.View>
<!-- removed -->
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<EventTrigger RoutedEvent="GotKeyboardFocus">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames BeginTime="0:0:0" Duration="0:0:0" Storyboard.TargetProperty="IsSelected">
<DiscreteBooleanKeyFrame Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
您还需要指定 SelectionMode="Single"
否则之前的项目将不会被取消selected
编辑
它向项目容器样式 (ListViewItem
) 添加了新的事件触发器,只要 GotKeyboardFocus
event occurs. It's bubbling event meaning it will bubble up the visual tree from any ListViewItem
child and finally reach ListViewItem
where it will trigger BooleanAnimationUsingKeyFrames
能够更改 Boolean
属性值的动画就会执行。在这种情况下,它不是真正的动画,因为它需要 0 秒,但它会将 IsSelected
属性(由 Storyboard.TargetProperty
指定)设置为 true
我想 post 使用 Command 和 CommandParameter 实现此解决方案的替代方法。
在您的 XAML 中将命令绑定到复选框。还将 CommandParameter 绑定到将传递给命令本身的值。请注意:因为 ListView 的 ItemSource 设置为 Observablecollection,所以您必须使用
更改为父 DataContextCommand="{Binding ElementName=NameOfListView,Path=DataContext.NameOfCommand}"
从 ViewModel DataContext 绑定命令。您也可以使用 Ancestor 来获取父数据上下文。
<ListView
Background="#f0f0f0"
Grid.Row="1"
ItemsSource="{Binding ListViewCollection}"
Name="ListView"
IsSynchronizedWithCurrentItem="True"
BorderThickness="0"
Margin="5">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}"
Command="{Binding ElementName=ListView,Path=DataContext.HideShowGraph}"
CommandParameter="{Binding TheValue, Mode=OneWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding TheText}" Header="#Cell" />
<GridViewColumn DisplayMemberBinding="{Binding TheVoltage}" Header="U[V]" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
然后在您的 ViewModel 中声明一个带参数的 RelayCommand 和相应的委托方法。
public class ViewModel : ViewModelBase
{
public ViewModel()
{
HideShowGraph = new RelayCommand<int>(foo => HideShowGraphExecute(foo));
}
public ICommand HideShowGraph { get; private set; }
private void HideShowGraphExecute(int foo)
{
//...evaluate foo
}
}
因此,如果选中 ListView 中的一个 Checkbox,则会调用 Command 并将 CommandParameter 的有界值(在此示例中 "TheValue")传递给委托方法 HideShowGraphExecute。使用此值,您可以区分复选框。
希望对您也有帮助!