1
作爲我正在處理的項目的一部分,我需要綁定到DataGridRow的IsSelected屬性。我們在ViewModel中使用此綁定來確定如何顯示數據(根據選擇的項目數量而定)。另外,我們使用IsSelected值來在Grid上手動選擇值,而不必讓我們的ViewModel知道DataGrid本身。如何以類別安全的方式綁定到DataGridRow的IsSelected屬性?
大部分情況下,我們都能正常工作(請參閱簡化示例)。問題是我們開始使用默認的DataGrid排序。此時,雙向綁定會導致我們得到一些意想不到的結果。要查看此行爲:
- 運行示例代碼提供了「約翰」
- 點擊,這將導致該行的「選擇」複選框成爲選中
- 單擊「名稱」頭分類。
- 點擊'David'將選擇和複選框更改爲David的行。
- 點擊'名稱'標題再次排序。
- 在這一點上,你可以看到我們現在莫名其妙地選擇並檢查了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));
}
}
}
}
感謝您的幫助。將SelectionMode設置爲Single將確實會阻止選擇多餘的行。但是,它不會真正解決我的問題。作爲項目的一部分,我的用戶需要能夠選擇多行。選定的行數對於確定如何顯示數據至關重要(見上文)。 – guxiyou
好吧,我明白了...所以你需要能夠選擇多行,但一次只檢查一個複選框? –
對不起,我沒有很好地解釋。問題不在於複選框,而在於選擇本身。當我選擇然後對項目進行排序時,我希望在排序之前我應該始終具有相同的選擇。排序本身不應該改變選擇(不管它是否綁定任何東西)。所以在我上面的步驟中,一切都很好,直到第5步。在這裏,我首先選擇了David,但是當排序完成時,我選擇了David和John。這種添加選擇是我想要防止的。 – guxiyou