ObservableCollectionに裏打ちされたDataGridがあります。一部のデータを変更するたびに、ObservableCollection全体をリモートサーバーに書き込みます。それから数ミリ秒後、サーバーから更新を受け取ります。デザインの性質上、DataGridで選択した要素を維持するために、サーバーからの更新でObservableCollectionの要素を1つずつ上書きします。
問題は、ある行のセルを編集してから別の行をクリックすると、そのセルを編集できなくなることです。編集する前に、別のセルをもう一度クリックする必要があります。
遅延後に要素を上書きすることと関係があることはわかっています。以下の例は問題を再現しています。何が起こっているのかについてのアイデアはありますか?
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;
}
}