2014-10-29 18 views
0

ViewModel如何正常反序列化View模型的一部分,而不會丟失以前的數據綁定?

public class MyViewModelType { 
    public PlayerElements Player { get; set; } 
    . 
    . 
    . 
} 

PlayerElements包含了許多綁定屬性:

public class PlayerElements : INotifyPropertyChanged { 
    ObservableCollection<IEntity> Angles { get; set; } 
    . 
    . 
    . 
    ObservableCollection<IBuilding> Castles { get; set; } 

    public string PlayerName { get; set; } 
} 

當我反序列化保存的模型,我做這樣的事情:

public MyViewModelType ViewModel { get; set; } 

    public LoadPlayerFromDisk(SomeDataModel dm){ 
     ViewModel.Player = new PlayerElements(vm.PlayerData); 
    } 

的問題是清楚的:當我創建新的PlayerElements時,我失去了所有綁定。我目前的解決方案是清除所有列表和手動添加:

ViewModel.Player.Angles.Clear(); 
foreach (var angel in vm.PlayerData.Angles) 
    ViewModel.Player.Angles.Add(angel); 

不用說 - 可怕的解決方案......

我想到了另一種選擇,將處理程序複製所有事件的新對象使用大劑量的反射。它是同類型不好解決的:我需要走整個樹(的ObservableCollection<T>財產,每個項目實現INotifyPropertyChanged,並且可以有更多的ObservableCollection<T>類型的孩子,等...)

所以,我怎麼能優雅地反序列化視圖模型,而不會丟失所有綁定?

+0

奇怪,你知道INotifyPropertyChanged是什麼,你爲什麼不在虛擬機中實現它? – Will 2014-10-29 15:56:55

+0

@我會實現它,爲了便於閱讀,我刪除了大量代碼。 – Tar 2014-10-29 16:34:26

回答

1

除非您沒有爲綁定引擎提交必要的屬性更改通知以查看您的財產分配,否則沒有理由丟失綁定。從你粘貼的代碼中,這似乎是這種情況。

你的物業制定者需要提高PropertyChanged事件由INotifyPropertyChanged暴露出來,例如:當綁定接收通知Player已經改變

public class MyViewModelType : INotifyPropertyChanged { 
    private PlayerElements _player; 

    public PlayerElements Player { 
     get { return _player; } 
     set { 
      _player = value; 
      OnPropertyChanged("Player"); 
     } 
    } 
    . 
    . 
    . 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string propertyName) { 
     var handler = this.PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName); 
    } 
} 

,它會自動從子屬性的通知說有綁定退訂和訂閱到新的Player的子屬性。您不應該自己複製任何事件訂閱。

+0

你確定嗎? Visual Studio的調試器顯示'(((System.MulticastDelegate)((ViewModel.Player.Angles).CollectionChanged)))._ invocationCount'等於'2',但在設置ViewModel.Player.Angles = deserializedPlayer.Angels後,調試器顯示'(System.MulticastDelegate)((ViewModel.Player.Angles).CollectionChanged)'是'null' ...是的,我確定'OnPropertyChanged(「Angles」)被觸發 – Tar 2014-10-29 16:31:37

+1

綁定引擎可能不立即更新;它可能會在更低的「DispatcherPriority」處更新。但是,是的,它應該接受變化。嘗試在更新'Angles'之後在'Background'優先級處調度'Dispatcher'的空行爲,並在行爲中設置一個斷點。然後,當斷點被擊中時,檢查你的事件處理程序。 – 2014-10-29 16:37:12

相關問題