簡體   English   中英

將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>

ItemSourceItemSource中一樣, ListViewItemSource綁定到ViewModel中數據類的ObservableCollection

現在,我想將每個列表視圖項目的Checkbox.IsChecked屬性連接到父級ListView.SelectedItems屬性以觸發它。 為什么? 因為我想顯示/隱藏一系列數據圖。 因此,如果選中了第一行中的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並傳遞一個參數來區分復選框。 但是正如我所說,我想使用該屬性。

這有可能還是有更好的想法來解決我的問題?

所選項目將是綁定到“項目”源的“項目”的類型。 如果項目來源為列表,則表示所選項目為學生。

據我了解您的問題,這是由CheckBoxListViewItem竊取焦點引起的。 如果要在單擊CheckBox時選擇項目,則可以使用動畫觸發,只要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"否則不會取消選擇上一個項目

編輯

它將新的事件觸發器添加到項目容器樣式( ListViewItem ),只要發生GotKeyboardFocus事件,該觸發器就會執行。 這是冒泡事件,表示它將從任何ListViewItem子項中冒出可視樹,並最終到達ListViewItem ,在此它將觸發BooleanAnimationUsingKeyFrames動畫,該動畫能夠更改Boolean屬性的Boolean 在這種情況下,它並不是真正的動畫,因為它花費了0秒,但是會將IsSelected屬性(由Storyboard.TargetProperty指定)設置為true

我想發布一種替代方法,以使用Command和CommandParameter實現此解決方案。

在您的XAML中,將命令綁定到復選框。 還要將CommandParameter綁定到一個值,該值將傳遞給Command本身。 請注意:由於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。 使用此值,您可以區分復選框。

希望它也有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM