2015-05-13 89 views
1

我很擔心MVVM數據綁定。將CheckBox的IsChecked屬性綁定到ListView的SelectedItems屬性

在我的例子中,我有一個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> 

ListViewItemSource被綁定到視圖模型數據類的ObservableCollection,因爲你在做MVVM。

現在我想將每個列表視圖項的Checkbox.IsChecked屬性連接到父項ListView.SelectedItems屬性來觸發它。爲什麼?因爲我想顯示/隱藏一系列數據圖。因此,如果選中第一行中的CheckBox,則顯示圖1.如果未選中第2行中的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並傳遞一個參數來區分複選框。但正如我所說的,我想使用這個屬性。

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

+0

當你使用綁定時'ListView.SelectedItem'不會是'ListViewItem'類型。這只是一個容器。它將與您收藏中的物品具有相同的類型。因此,如果'ItemsSource'綁定到'List ',那麼'ListView.SelectedItem(s)'將給出'MyItemClass',那應該是你綁定屬性的類型 – dkozl

+0

是的,我知道!但那不是我的問題。 SelectedItem僅在點擊行時觸發,而不在複選框上觸發!我知道我必須將屬性綁定到與ItemSource相同類型的SelectedItem。這對我來說很清楚! –

+0

我知道這不是你的問題,因此只有評論。據我瞭解,你的問題是'ListViewItem'沒有被選中,因爲'CheckBox'獲得焦點。當'CheckBox'被點擊時,你希望ListViewItem被選中嗎? – dkozl

回答

0

據我瞭解你的問題是由CheckBox盜竊重點從ListViewItem引起的。如果您想選擇項目時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事件發生。這是bubbling event這意味着它會從任何ListViewItem孩子的視覺樹中冒出來,並最終到達ListViewItem,在那裏它將觸發BooleanAnimationUsingKeyFrames動畫,該動畫可以更改Boolean屬性的值。在這種情況下,它不是一個真正的動畫,因爲它需要0秒,但它會將IsSelected屬性(由Storyboard.TargetProperty指定)設置爲true

+0

嘿dkozi非常感謝你。這是解決方案。也許你可以解釋一下這些xmal標籤在做什麼。好吧,我有解決方案,但我不明白。 –

+0

@SebastianRichter檢查我的編輯。我已經添加了一些解釋 – dkozl

0

所選項目將成爲綁定到項目源的項目的類型。如果商品來源爲列表,則意味着所選商品將爲學生。

+0

你可以添加更多的細節給你答案。我不確定這足以解決問題,儘管它似乎指向了正確的方向。 – Peanut

0

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

在您的XAML中將命令綁定到複選框。還將CommandParameter綁定到將傳遞給Command本身的值。請注意:由於ListView控件的的ItemSource設置爲一個ObservableCollection你必須改變父的DataContext與

命令= 「{綁定的ElementName = NameOfListView,路徑= 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一個複選框被選中調用的命令和CommandParameter的有限值,在這個例子中「TheValue」,傳遞給委託方法HideShowGraphExecute。使用此值可以區分複選框。

希望它也有幫助!

相關問題