2017-05-31 57 views
0

您好我有這勢必與TrulyObservableCollection,每當我試圖通過爲textInput的DataGrid單元格編輯單元格失去專注每個鍵後輸入一個WPF的DataGrid,WPF的Datagrid與TrulyObservableCollection失去專注於編輯

public sealed class TrulyObservableCollection<T> : ObservableCollection<T> 
    where T : INotifyPropertyChanged 
{ 
    public TrulyObservableCollection() 
    { 
     CollectionChanged += FullObservableCollectionCollectionChanged; 
    } 

    public TrulyObservableCollection(IEnumerable<T> pItems) 
     : this() 
    { 
     foreach (var item in pItems) { 
      this.Add(item); 
     } 
    } 

    private void FullObservableCollectionCollectionChanged(object sender, 
     NotifyCollectionChangedEventArgs e) 
    { 
     if (e.NewItems != null) { 
      foreach (Object item in e.NewItems) { 
       ((INotifyPropertyChanged)item).PropertyChanged += ItemPropertyChanged; 
      } 
     } 
     if (e.OldItems != null) { 
      foreach (Object item in e.OldItems) { 
       ((INotifyPropertyChanged)item).PropertyChanged -= ItemPropertyChanged; 
      } 
     } 
    } 

    private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     try { 
      var a = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset); 
      OnCollectionChanged(a); 
     } 
     catch { 
      // ignored 
     } 
    } 
} 

下面是我的視圖模型,這是綁定到Datagrid的,

public TrulyObservableCollection<SubLotModel> SubLotCollection 
{ 
    get { return _subLotCollection; } 
    set 
    { 
     _subLotCollection = value; 
     NotifyOfPropertyChange(() => SubLotCollection); 
     SerialNumberAdded = _subLotCollection.Count; 
    } 
} 

在DataGrid我有被綁定在SublotCollection數量屬性的文本框列,

<DataGridTemplateColumn Header="Quantity"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <TextBox Text="{Binding Quantity, ValidatesOnDataErrors=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox> 

     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 

只要我在texbox列中鍵入一個有效的鍵,單元失去焦點。

+2

我的猜測是,每次在信視圖模型輸入時間'Quantity'屬性更新了引發'PropertyChanged'事件,這會導致您的'TrulyObservableCollection'通過'NotifyCollectionChangedAction.Reset'引發'CollectionChanged',從而導致'DataGrid'重建自身,導致以前集中的編輯器失去焦點(可能不是甚至是同一個編輯器,但是新創建的實例在它的位置)。 – Grx70

+1

@ Grx70:好點。但是,爲什麼每當項目的屬性發生變化時,您(OP)都會發起重置事件,即使用TrulyObservableCollection類的目的是什麼? – mm8

+0

我正在使用TrulyObservable集合,以便收集集合中的項目時也能收到通知。 – Vinay

回答

1

診斷

正如我在我的評論,爲什麼你的編輯器失去焦點的原因一提的是這一連串事件的:

  • 你在信中鍵入,新的文本推到視圖模型因爲UpdateSourceTrigger=PropertyChanged
  • Quantity財產上的視圖模型的更新和PropertyChanged事件引發
  • TrulyObservableCollection處理PropertyChanged事件ND在後果引發CollectionChanged事件與動作設定爲NotifyCollectionChangedAction.Reset
  • DataGrid被設計爲重建本身在這樣的場合,因此,每個單元被從頭(再模板)構成,最終有那裏曾經是一個完全新TextBox您所使用的信

重點鍵入不返回到新TextBox因爲DataGrid是沒有真正意識到它的存在(因爲它在DataTemplate的已定義)。即使您使用DataGridTextColumn(但您可以檢查),我也不認爲焦點會恢復。

所以這裏的核心問題是NotifyCollectionChangedAction.Reset。當一件物品只有一個物品發生了變化時,似乎總是誇大其詞。

解決方案

更合理的選擇是與NotifyCollectionChangedAction.Replace包括哪些項目是「更換」的信息,以提高CollectionChanged。再加上一些改進這裏是一個集合的實現,應該表現得像你希望(我測試了它,它所做的那樣):

public class TrulyObservableCollection<T> : ObservableCollection<T> 
    where T : INotifyPropertyChanged 
{ 
    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
    { 
     base.OnCollectionChanged(e); 
     if (e.NewItems != null) 
     { 
      foreach (INotifyPropertyChanged inpc in e.NewItems) 
        inpc.PropertyChanged += Item_PropertyChanged; 
     } 
     if (e.OldItems != null) 
     { 
      foreach (INotifyPropertyChanged inpc in e.OldItems) 
        inpc.PropertyChanged -= Item_PropertyChanged; 
     } 
    } 

    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     var index = IndexOf((T)sender); 
     var args = new NotifyCollectionChangedEventArgs(
      action: NotifyCollectionChangedAction.Replace, 
      newItem: sender, 
      oldItem: sender, 
      index: index); 
     //no need to call the override since we've already 
     //subscribed to that item's PropertyChanged event 
     base.OnCollectionChanged(args); 
    } 
} 
+0

謝謝,這個解決方案似乎工作。 – Vinay