我的情况与其他帖子略有不同,我无法用其他trhread解决它。那就是我问的原因。
我有一个通过反序列化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个视图,一个用于显示所有叶子,另一个用于编辑一个叶子。我已经实现了提交和回滚,因此我使用来回传递新值来存储旧值。
为此,我将对象复制为备份变量,然后通过绑定到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 :(得分:0)
你的RaisePropertyChanged
被忽略的原因是叶子类没有实现INotifyOropertyChanged
。通常,模型被包装到视图模型中,然后实现INotifyPropertyChange
d以通知视图已发生的事情。
但是,您也可以直接在模型类上实现INotifyPropertyChanged
。要实现INotifyPropertyChanged
,每个属性都必须提升propty更改事件。
public string Property {
get { ... }
set {
if (_propertyField == value)
return;
_propertyField = value;
RaisePropertyChanged("Property");
}
}
代码假定有一个方法RaisePropertyChanged
实际上会使PropertyChangedEvent
加密。
答案 1 :(得分:0)
谢谢大家的帮助。 调查你的建议我发现了一个稍微不同的解决方案;正确地说,问题是叶子字段不是“可观察的”,因此它们不会生成通知事件。
我注意到如果添加或删除配置文件,绑定会更新。
所以我决定做的不是直接编辑叶子而是替换节点。 我不喜欢的是我必须创建一个节点来替换旧的节点,这会分配更多的内存......但对于我所拥有的小数据,它可以在不对app性能产生任何重大影响的情况下工作记忆足印。
以下是我的工作:
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个参数的构造函数,以便代码可以是:
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;
}