Chạy ví dụ sau và bạn sẽ thấy lý do tại sao nó không hoạt động.
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">
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding SelectedItem, ElementName=dataGrid}"/>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding SelectedItem}"/>
<DataGrid x:Name="dataGrid" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding FirstName}"/>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
</Window>
Mã-đằng sau:
namespace DataGridTest
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
public partial class MainWindow : Window, INotifyPropertyChanged
{
private readonly ICollection<Person> items;
private Person selectedItem;
public MainWindow()
{
InitializeComponent();
this.items = new ObservableCollection<Person>();
this.items.Add(new Person
{
FirstName = "Kent",
LastName = "Boogaart"
});
this.items.Add(new Person
{
FirstName = "Tempany",
LastName = "Boogaart"
});
this.DataContext = this;
}
public ICollection<Person> Items
{
get { return this.items; }
}
public Person SelectedItem
{
get { return this.selectedItem; }
set
{
this.selectedItem = value;
this.OnPropertyChanged("SelectedItem");
}
}
private void OnPropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class Person
{
public string FirstName
{
get;
set;
}
public string LastName
{
get;
set;
}
public override string ToString()
{
return FirstName + " " + LastName;
}
}
}
Như bạn có thể nhìn thấy khi chạy, chọn "mới" liên tiếp gây ra một giá trị trọng điểm được thiết lập như là mục đã chọn trong DataGrid
. Tuy nhiên, WPF không thể chuyển đổi mục được gửi tới một số Person
, do đó, ràng buộc SelectedItem
không chuyển đổi được.
Để khắc phục điều này, bạn có thể đặt bộ chuyển đổi trên liên kết của mình để phát hiện con dấu và trả lại null
khi được phát hiện. Dưới đây là một chuyển đổi mà không vậy:
namespace DataGridTest
{
using System;
using System.Windows.Data;
public sealed class SentinelConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && string.Equals("{NewItemPlaceholder}", value.ToString(), StringComparison.Ordinal))
{
return null;
}
return value;
}
}
}
Như bạn thấy, nó là một sự cần thiết không may để kiểm tra so với giá trị ToString()
của sentinel, bởi vì nó là một loại nội bộ. Bạn có thể cách khác (hoặc ngoài ra) kiểm tra xem GetType().Name
là NamedObject
.
5 năm sau, nhưng cũng có thể đặt nó ở đây: Bạn có thể so sánh nó với CollectionView.NewItemPlaceholder, đó là điều tương tự bạn đang làm, mà không cần phải ghi chuỗi "{NewItemPlaceholder}" trên mã của bạn. –