将CheckBox IsChecked属性绑定到ListView的SelectedItems属性

时间:2015-05-13 08:11:29

标签: c# wpf listview mvvm data-binding

我很难与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>

ItemSource的{​​{1}}绑定到ViewModel中数据类的ListView,就像在MVVM中一样。

现在我想将每个列表视图项的ObservableCollection属性连接到父Checkbox.IsChecked属性以触发它。为什么?因为我想显示/隐藏一系列数据图。因此,如果选中第一行中的ListView.SelectedItems,则显示图1.如果未选中第2行中的CheckBox,请隐藏图2,依此类推。像这样:

CheckBox

要触发此属性,您必须在GUI中单击两次。首先检查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); } } } } ,然后再次单击该行以触发并隐藏图形。但我希望在点击CheckBox后立即触发SelectedItems属性。

现在我将命令绑定到CheckBox并传递参数以区分复选框。但正如我所说,我想使用该属性。

这可能或者有更好的想法来解决我的问题吗?

3 个答案:

答案 0 :(得分:0)

所选项目将是绑定到项目源的项目类型。如果项目来源是列表意味着所选项目将是学生。

答案 1 :(得分:0)

据我了解你的问题,CheckBoxListViewItem窃取了焦点。如果您想在点击CheckBox时选择项目,只要ListViewItem中的某些内容获得焦点并将IsSelected设置为真,就可以使用动画触发

<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",否则以前的项目将无法取消选择

修改

它向项容器样式(ListViewItem)添加了新的事件触发器,该事件将在GotKeyboardFocus事件发生时执行。它的bubbling event意味着它会从任何ListViewItem子项中冒出可视树,最后到达ListViewItem,它会触发BooleanAnimationUsingKeyFrames动画,它可以改变价值Boolean属性。在这种情况下,它不是真正的动画,因为它需要0秒,但它会将IsSelected属性(由Storyboard.TargetProperty指定)设置为true

答案 2 :(得分:0)

我想发布一个替代方案来使用Command和CommandParameter实现此解决方案。

在您的XAML中将命令绑定到复选框。还要将CommandParameter绑定到一个值,该值将传递给Command本身。请注意:因为ListView的ItemSource设置为Observablecollection,您必须使用

更改为父DataContext
  

Command =“{Binding ElementName = NameOfListView,Path = DataContext.NameOfCommand}”

从ViewModel DataContext绑定Command。您还可以使用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。使用此值,您可以区分复选框。

希望它也有帮助!