我有一个由ObservableCollection支持的DataGrid。每当我更改一些数据时,我都会将整个ObservableCollection写入远程服务器。然后几毫秒后我从服务器返回更新。由于设计的性质以及为了在DataGrid中维护所选元素,我使用来自服务器的更新逐个覆盖ObservableCollection中的元素。
问题是我可以编辑一行的单元格,然后单击进入另一行,我将无法编辑该单元格。在我可以编辑之前,我必须再次点击一个不同的单元格。
我知道它与延迟后覆盖元素有关,下面的例子再现了这个问题。对于发生了什么的任何想法?
XAML:
<Window x:Class="WpfApplication3.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
Title="Window1" Height="300" Width="300">
<Grid>
<dg:DataGrid Name="dg" AutoGenerateColumns="True"/>
</Grid>
</Window>
代码背后的代码:
using System;
using System.Windows;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Threading;
namespace WpfApplication3
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
mPeople = new People();
dg.ItemsSource = mPeople.mList;
}
public People mPeople;
}
public class People : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public People()
{
mList = new ObservableCollection<Person>();
mList.Add(CreatePerson("Jacob", "Lewis"));
mList.Add(CreatePerson("Scott", "Doe"));
mList.Add(CreatePerson("Corey", "Dorn"));
dp = new DispatcherTimer();
dp.Tick += new EventHandler(dp_Tick);
dp.Interval = new System.TimeSpan(0, 0, 0, 0,100);
}
public Person CreatePerson(string first, string last)
{
Person p = new Person(first, last);
p.EditCompleted += new Person.EditCompletedDelegate(OnPersonEditComplete);
return p;
}
public void OnPersonEditComplete(Person p)
{
dp.Start();
}
void dp_Tick(object sender, EventArgs e)
{
dp.Stop();
for (int i = 0; i < mList.Count; i++) {
mList[i] = CreatePerson(mList[i].FirstName, mList[i].LastName);
}
}
public ObservableCollection<Person> mList;
private DispatcherTimer dp;
}
public class Person : INotifyPropertyChanged, IEditableObject
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public delegate void EditCompletedDelegate(Person p);
public EditCompletedDelegate EditCompleted;
void IEditableObject.EndEdit()
{
EditCompleted(this);
}
void IEditableObject.BeginEdit() { }
void IEditableObject.CancelEdit() { }
public Person(string first, string last)
{
FirstName = first;
LastName = last;
}
public string FirstName
{
get { return mFirstName; }
set { mFirstName = value; PropertyChanged(this, new PropertyChangedEventArgs("FirstName")); }
}
public string LastName
{
get { return mLastName; }
set { mLastName = value; PropertyChanged(this, new PropertyChangedEventArgs("LastName")); }
}
private string mFirstName;
private string mLastName;
}
}