2010-04-10 100 views
14

我有一個啓用多選的數據網格。我需要改變viewmodel中的選擇。但是,SelectedItems屬性是隻讀的,不能直接綁定到視圖模型中的屬性。那麼,我如何向觀點表明選擇已經改變?WPF DataGrid多選選項綁定

+0

參見http://stackoverflow.com/questions/1579700/wpf-toolkit-datagrid-multi-select-how-to-get-selecteditems-out – 2012-11-21 14:49:39

回答

6

我還沒有使用DataGrid很多,但一種適用於ListView的技術是綁定到個人ListViewItemIsSelected屬性。只需爲列表中的每個對象設置爲true,然後它就會被選中。

也許代表DataGrid中的一行的對象也具有IsSelected屬性,並且可以以這種方式使用?

17

安迪是正確的。 DataGridRow.IsSelected是一個依賴屬性,可以通過數據綁定來控制ViewModel中的選擇。下面的示例代碼演示了這一點:

<Window x:Class="DataGridMultiSelectSample.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:tk="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 
     <tk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" EnableRowVirtualization="False"> 
      <tk:DataGrid.Columns> 
       <tk:DataGridTextColumn Header="Value" Binding="{Binding Value}" /> 
      </tk:DataGrid.Columns> 
      <tk:DataGrid.RowStyle> 
       <Style TargetType="tk:DataGridRow"> 
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> 
       </Style> 
      </tk:DataGrid.RowStyle> 
     </tk:DataGrid> 
     <Button Content="Select Even" Click="Even_Click" /> 
     <Button Content="Select Odd" Click="Odd_Click" /> 
    </StackPanel> 
</Window> 

using System.ComponentModel; 
using System.Windows; 

namespace DataGridMultiSelectSample 
{ 
    public partial class Window1 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
      DataContext = new[] 
           { 
            new MyViewModel {Value = "Able"}, 
            new MyViewModel {Value = "Baker"}, 
            new MyViewModel {Value = "Charlie"}, 
            new MyViewModel {Value = "Dog"}, 
            new MyViewModel {Value = "Fox"}, 
           }; 
     } 

     private void Even_Click(object sender, RoutedEventArgs e) 
     { 
      var array = (MyViewModel[]) DataContext; 
      for (int i = 0; i < array.Length; ++i) 
       array[i].IsSelected = i%2 == 0; 
     } 

     private void Odd_Click(object sender, RoutedEventArgs e) 
     { 
      var array = (MyViewModel[])DataContext; 
      for (int i = 0; i < array.Length; ++i) 
       array[i].IsSelected = i % 2 == 1; 
     } 
    } 

    public class MyViewModel : INotifyPropertyChanged 
    { 
     public string Value { get; set; } 

     private bool mIsSelected; 
     public bool IsSelected 
     { 
      get { return mIsSelected; } 
      set 
      { 
       if (mIsSelected == value) return; 
       mIsSelected = value; 
       if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs("IsSelected")); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 
} 

一定要設置EnableRowVirtualisation="False" DataGrid的元素,否則有一個風險,即IsSelected綁定掉出良好狀態的。

+0

完美。並感謝示例代碼 - 很好地說明了它。 – 2011-05-17 08:49:29

+0

謝謝。希望你不介意我在你的例子中加入'EnableRowVirtualisation =「False」',因爲沒有它,就會出現綁定不在新行上的錯誤。 – 2012-11-22 16:51:04

3

夥計們,感謝您的幫助。我的問題解決了。我認爲這個問題對於新的WPF開發人員來說很常見,所以我會在這裏重申我的問題以及更詳細的解決方案,以防其他人遇到同樣的問題。

問題:我有一個多選音頻文件啓用數據網格。網格有多個列標題。用戶可以多選幾行。當他點擊播放按鈕時,音頻文件將按照列標題(例如列A)的順序播放。播放開始時,多重選擇被清除,只有當前播放的文件被高亮顯示。當所有文件的播放結束時,多重選擇將被重新顯示。播放是在視頻模型中完成的。如您所見,這裏有兩個問題:1)如何從視圖模型中選擇當前正在播放的文件,以及2)如何從視圖模式向視圖發信號表示播放已完成並重新顯示多重選擇。

解決方案:要解決第一個問題,我在viewmodel中創建了一個屬性,該屬性綁定到視圖的SelectedIndex屬性以選擇當前正在播放的文件。爲了解決第二個問題,我在視圖模型中創建了一個布爾屬性來指示播放完成。在後面的代碼中,我訂閱了布爾屬性的PropertyChanged事件。在事件處理程序中,視圖的SelectedItems屬性從保存的多選中重新創建(SelectedItems的內容已保存到列表中,SelectedItems在播放開始時被清除)。起初,我無法重新創建SelectedItems。事實證明,問題是由於通過第二個線程發起的重新創建。 WPF不允許這樣做。解決方法是使用Dispatcher.Invoke()讓主線程完成工作。對於有經驗的開發人員來說,這可能是一個非常簡單的問題,但對於新手來說,這是一個小挑戰。無論如何,來自不同人的很多幫助。

2

只需在任何MultiSelector派生類上使用SelectedItems,並使用方法Add,Remove,Clear就可以返回IList。

問候, 羅賓