2012-02-22 6 views
0

私の状況は他の投稿と若干異なり、他のtrhreadsで解決できませんでした。それで私がなぜ尋ねるのか。MVVM Light - 子ネストされた編集から親ビューを更新することができません

私のようなXMLをデシリアライズから取得されたクラスを持っている:

<?xml version="1.0" encoding="UTF-8"?> 
<node> 
    <leaf> 
     <name>node 1</name> 
     <text>text 1</text> 
     <url>url 1</url> 
    </leaf> 
    <leaf> 
     <name>node 2</name> 
     <text>text 2</text> 
     <url>url 2</url> 
    </leaf> 
</node> 

ので、クラスは次のとおりです。

[XmlRoot("node")] 
public class csNodeList 
{ 
    public csNodeList() 
    { 
     Leaf = new csLeafCollection(); 
    } 

    [XmlElement("leaf")] 
    public csLeafCollection Leaf 
    { 
     get; 
     set; 
    } 
} 

public class csLeaf 
{ 
    public csLeaf() 
    { 
     Name =""; 
     Description = ""; 
     Address = ""; 
    } 

    [XmlElement("name")] 
    public string Name 
    { 
     get; 
     set; 
    } 

    [XmlElement("text")] 
    public string Description 
    { 
     get; 
     set; 
    } 

    [XmlElement("url")] 
    public string Address 
    { 
     get; 
     set; 
    } 
} 

public class csLeafCollection : System.Collections.ObjectModel.ObservableCollection<csLeaf> 
{ 
} 

その後、私は2つのビュー、すべてのリーフを示すために1つずつを持っています1つのリーフを編集します。コミットとロールバックを実装していますので、新しい値を渡すために前後のメッセージングを使用し、古い値を格納します。

これを行うには、オブジェクトをバックアップ変数にコピーしてから、XAMLビューにバインドすることで関連付けられたオブジェクトを変更します。このように(理論上は)ViewModelデータへの変更が反映されます。 変更をコミットするとバックアップ変数(これは90%)が破棄され、バックアップ変数からロールバックする必要がある場合に便利です。

MAINVIEW:メッセージを使用して

public const string listPropertyName = "list"; 
private csNodeList _list = new csNodeList(); 
public csNodeList list 
{ 
    get 
     { 
     return _list; 
    } 
    set 
    { 
     Set(listPropertyName, ref _list, value, false); 
    } 
} 

私は、ノードの新しい値を返送し、私が正しい位置にそれらを置く:

private void DoSomething(csMessage message) 
{ 
    csMessage rmessage; 
    if (message != null) 
    { 
     switch (message.destination) 
     { 
      case csMessage.e2MessageDest.updateNode: 
      //_editP should be fine. 
      list.Leaf[list.Leaf.IndexOf(_editP)].Name = ((csLeaf)message.payload).Name; 
      list.Leaf[list.Leaf.IndexOf(_editP)].Text= ((csLeaf)message.payload).Text; 
      list.Leaf[list.Leaf.IndexOf(_editP)].Address = ((csLeaf)message.payload).Address; 
      RaisePropertyChanged(listPropertyName , null, _list, true); 
      break; 
     } 
    } 
} 

コードが正しく実行されると、アイテムがありますかわった。

しかし、RaisePropertyChangedは無視されます。私はlistPropertyNameで変更しなくても試してみました。私はアプリからの変更出口を保存し、私が正しく

を保存し、新しい値を参照してください取り戻す場合

あなたは私を助けてくださいことはできますか?

おかげで、 マッシモ

答えて

0

ご協力いただきありがとうございます。 提案の調査私はわずかに異なる解決策を見つけました。リーフフィールドが「観測可能」でないため、通知イベントを生成しないという問題が正しく述べられています。

私がプロファイルを追加または削除すると、バインディングが更新されていることに気付きました。

私は、リーフを直接編集するのではなく、ノードを置き換えることを決めました。 私は好きではないのは、古いものを置き換えるノードを作成しなければならないということです。これは少しのメモリを割り当てます...しかし、私のような小さなデータの場合、アプリケーションのパフォーマンス/メモリフットプリント。ここで

は、私が何をすべきかです:

 csLeaf _leaf = new slLeaf(); 
     _leaf.Name = ((csLeaf)message.payload).Name; 
     _leaf.Text= ((csLeaf)message.payload).Text; 
     _leaf.URL = ((csLeaf)message.payload).Address; 
     list.Leaf[list.Leaf.IndexOf(_editP)] = _leaf; 

コードができるように、私はそれは3つのパラメータでコンストラクタを追加し強化したコードの最適化readabiltyへ:

 csLeaf _leaf = new slLeaf(((csLeaf)message.payload).Name, ((csLeaf)message.payload).Text, ((csLeaf)message.payload).Address); 
     list.Leaf[list.Leaf.IndexOf(_editP)] = _leaf; 

コンストラクタがされます:

public csLeaf(string _name, string _description, string _address) 
{ 
    Name = _name; 
    Description = _description; 
    Address = _address; 
} 
0

はあなたRaisePropertyChangedが無視される理由は、帽子ヨールリーフクラスデINotifyOropertyChangedを実装していません。通常、モデルはビューモデルにラップされ、ビューモデルにINotifyPropertyChange dを実装して、何かが発生したことをビューハットに通知します。

ただし、INotifyPropertyChangedをモデルクラスに直接実装することもできます。 INotifyPropertyChangedを実装するには、各プロパティが変更されたイベントを呼び出す必要があります。

public string Property { 
    get { ... } 
    set { 
     if (_propertyField == value) 
      return; 
     _propertyField = value; 
     RaisePropertyChanged("Property"); 
    } 
} 

コードが前提帽子は実際PropertyChangedEvent taises方法RaisePropertyChangedあります。

+0

これはいいですが、MVVMのセットを使用していますが、モデルでも使用できますか? ViewModelレイヤーとModelレイヤーが「混ざり合っている」にもかかわらず、私はそれを試しませんでした。間違っていますか? –

+0

その他の考え:ノードを追加または削除するとすぐに更新されます。コレクションはIObservableなので、それですか?アイテムをIObservableにすることはできますか? しかし、もう一度:これはViewModelレイヤをモデルレイヤで台無しにしていますか? –

+0

通常、ViewModel(ViewModelBaseから継承)内にモデルをラップし、モデルの各プロパティのプロパティを実装します。これらのラッパー・プロパティーのそれぞれは、プロパティー変更通知機能を追加するようになりました。プロパティフィールド(この例では '_propertyField')に書き込む代わりに、モデルのプロパティ(つまり、' _model.Property')に書き込むことになります。また、**モデルで通知を実装することもできます**。個人的には、ビューに関連する追加のプロパティを許可するため、最初のアプローチを好みます。 – AxelEckenberger

関連する問題