2014-01-30 28 views
1

作爲我正在處理的項目的一部分,我需要綁定到DataGridRow的IsSelected屬性。我們在ViewModel中使用此綁定來確定如何顯示數據(根據選擇的項目數量而定)。另外,我們使用IsSelected值來在Grid上手動選擇值,而不必讓我們的ViewModel知道DataGrid本身。如何以類別安全的方式綁定到DataGridRow的IsSelected屬性?

大部分情況下,我們都能正常工作(請參閱簡化示例)。問題是我們開始使用默認的DataGrid排序。此時,雙向綁定會導致我們得到一些意想不到的結果。要查看此行爲:

  1. 運行示例代碼提供了「約翰」
  2. 點擊,這將導致該行的「選擇」複選框成爲選中
  3. 單擊「名稱」頭分類。
  4. 點擊'David'將選擇和複選框更改爲David的行。
  5. 點擊'名稱'標題再次排序。
  6. 在這一點上,你可以看到我們現在莫名其妙地選擇並檢查了2行(約翰和大衛)。

正如你可以看到綁定工作得很好,只要你不排序,然後它就會失控。我需要一種方法來綁定IsSelected屬性,排序後沒有意外的行爲。請注意:我知道我可以通過將綁定模式更改爲OneWayToSource來獲得所需的大部分內容,但我確實需要2路綁定。

非常感謝您的幫助!

XAML:

<Window x:Class="DataGridTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <DataGrid Name="UIDataGrid" AutoGenerateColumns="False" IsReadOnly="True"> 
      <DataGrid.Resources> 
       <Style TargetType="{x:Type DataGridRow}"> 
        <Setter Property="IsSelected" Value="{Binding IsSelected}"></Setter> 
       </Style> 
      </DataGrid.Resources> 
      <DataGrid.Columns> 
       <DataGridCheckBoxColumn Header="Selected" Binding="{Binding Path=IsSelected}"></DataGridCheckBoxColumn> 
       <DataGridTextColumn Header="Name" Binding="{Binding Name}"/> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 

代碼背後:

using System; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Windows; 

namespace DataGridTest 
{ 
    public partial class MainWindow : Window 
    { 

     public ObservableCollection<Selectable> Selectables { get; set; } 

     public MainWindow() 
     { 
      InitializeComponent(); 

      Selectables = new ObservableCollection<Selectable>(); 
      Selectables.Add(new Selectable {Name = "Adam", IsSelected = false}); 
      Selectables.Add(new Selectable {Name = "John", IsSelected = false}); 
      Selectables.Add(new Selectable {Name = "David", IsSelected = false}); 

      UIDataGrid.ItemsSource = Selectables; 
     } 
    } 

    public class Selectable : PropertyChangedNotifier 
    { 
     private bool _isSelected; 
     public bool IsSelected 
     { 
      get{ return _isSelected; } 
      set 
      { 
       _isSelected = value; 
       RaisePropertyChanged("IsSelected"); 
      } 
     } 

     private string _name; 
     public string Name 
     { 
      get { return _name; } 
      set 
      { 
       _name = value; 
       RaisePropertyChanged("Name"); 
      } 
     } 
    } 

    [Serializable] 
    public abstract class PropertyChangedNotifier : INotifyPropertyChanged 
    { 
     [field: NonSerialized] 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected void RaisePropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 

回答

1

您需要設置選擇模式爲單上的數據表。當我用你的示例代碼做到這一點時,它按照你所希望的方式工作。

<DataGrid Name="UIDataGrid" AutoGenerateColumns="False" SelectionMode="Single" IsReadOnly="True"> 
+0

感謝您的幫助。將SelectionMode設置爲Single將確實會阻止選擇多餘的行。但是,它不會真正解決我的問題。作爲項目的一部分,我的用戶需要能夠選擇多行。選定的行數對於確定如何顯示數據至關重要(見上文)。 – guxiyou

+0

好吧,我明白了...所以你需要能夠選擇多行,但一次只檢查一個複選框? –

+0

對不起,我沒有很好地解釋。問題不在於複選框,而在於選擇本身。當我選擇然後對項目進行排序時,我希望在排序之前我應該​​始終具有相同的選擇。排序本身不應該改變選擇(不管它是否綁定任何東西)。所以在我上面的步驟中,一切都很好,直到第5步。在這裏,我首先選擇了David,但是當排序完成時,我選擇了David和John。這種添加選擇是我想要防止的。 – guxiyou

相關問題