为什么INotifyPropertyChanged不更新代码后面的局部变量
本文关键字:局部变量 代码 INotifyPropertyChanged 更新 为什么 | 更新日期: 2023-09-27 18:17:27
我有两个类,Node和Connection。Node的名称和编号作为属性,Connection的字面意思是关于两个节点之间的连接信息。我使用这两个类作为observable collection声明静态。NodeNubmer和NodeName属性的CollectionPropertyChangedEventHandler在Node类中实现,因此当UI中任何节点的信息通过数据绑定发生变化时,UI和节点信息后面的代码都会发生变化。但是,Connection中的节点信息不会发生变化,例如在UI中更改了节点名称。下面是部分代码。如何更新节点信息连接时,它的变化在节点?
public Class Node: INotifyPropertyChanged
{
private int _nodeNumber;
private string _nodeName;
public int NodeNumber
{
get
{
return _nodeNumber;
}
set
{
_nodeNumber = value;
OnPropertyChanged("NodeNumber");
}
}
public string NodeName
{
get
{
return _nodeName;
}
set
{
_nodeName = value;
OnPropertyChanged("NodeName");
}
}
public event PropertyChangedEventHandler PropertyChanged;
// constructor
public Node(int nodeNumber, string nodeName)
{
_nodeNumber = nodeNumber;
_nodeName = nodeName;
}
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public Class Connection: INotifyPropertyChanged
{
private int _sourceNumber;
private int _destNamber;
private string _sourceName;
private string _destName;
public int SourceNumber
{
get
{
return _sourceNumber;
}
set
{
_sourceNumber = value;
OnPropertyChanged("SourceNumber");
}
}
public int DestNumber
{
get
{
return _destNumber;
}
set
{
_destNumber = value;
OnPropertyChanged("DestNumber");
}
}
public string SourceName
{
get
{
return _sourceName;
}
set
{
_sourceName = value;
OnPropertyChanged("SourceName");
}
}
public string DestName
{
get
{
return _destName;
}
set
{
_destName = value;
OnPropertyChanged("DestName");
}
}
public event PropertyChangedEventHandler PropertyChanged;
// constructor
public Connection(int sourceNumber, int destNumber)
{
_sourceNumber = sourceNumber;
_destNumber = destNumber;
// I guess this code is the reason why SourceName/DestName isn't changed when its node's name changed in UI, but I don't know how to fix this code.
// NodeInfo is ObservableCollection of Node
SourceName = NodeInfo.Collection[sourceNumber-1].NodeName;
DestName = NodeInfo.Collection[destNumber-1].NodeName;
}
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
我完全同意@mike z的观点。我认为如果你的连接类看起来像这样(BaseVM是一个实现INotifyPropertyChanged接口的类,为了简单起见,这里省略了),你的生活会容易得多:
public class Connection : BaseVM
{
public Connection(string name, Node a, Node b)
{
this.Name = name;
this.NodeA = a;
this.NodeB = b;
}
string _name;
public string Name
{
get { return _name; }
set
{
if (_name == value) return;
_name = value;
Notify( "Name" );
}
}
Node _nodeA;
public Node NodeA
{
get { return _nodeA; }
set
{
if (_nodeA == value) return;
_nodeA = value;
Notify( "NodeA" );
}
}
Node _nodeB;
public Node NodeB
{
get { return _nodeB; }
set
{
if (_nodeB == value) return;
_nodeB = value;
Notify( "NodeB" );
}
}
那么您可以在XAML中使用{Binding NodeA.Name}
(假设Connection作为您的数据上下文)。
public string AName
{
get { return (string)GetValue (ANameProperty); }
set { SetValue (ANameProperty, value); }
}
public static readonly DependencyProperty ANameProperty =
DependencyProperty.Register ("AName", typeof (string), typeof (Connection), new PropertyMetadata (""));
然后你必须手动设置绑定:
public Connection(string name, Node a, Node b)
{
// ...
this.AName = a.Name;
// to keep these updated, there needs to be a binding between the two
var binding = new Binding ("Name");
binding.Source = this.NodeA;
BindingOperations.SetBinding (this, ANameProperty, binding);
}
但正如@mike z所建议的,前者可能更符合你的要求。我有一个完整的例子:
- XAML小提琴
- CS小提琴