C# 我需要在基类和子类的情况下定义INotifyPropertyChanged
我有一个C# 我需要在基类和子类的情况下定义INotifyPropertyChanged,c#,wpf,inotifypropertychanged,C#,Wpf,Inotifypropertychanged,我有一个基类: public abstract class WiresharkFile { protected string _fileName; protected int _packets; protected int _packetsSent; protected string _duration; public int Packets { get { return _packets; } set { _pa
基类
:
public abstract class WiresharkFile
{
protected string _fileName;
protected int _packets;
protected int _packetsSent;
protected string _duration;
public int Packets
{
get { return _packets; }
set { _packets = value; }
}
public int PacketsSent
{
get { return _packetsSent; }
set { _packetsSent = value; }
}
}
而这个子类:
public class Libpcap : WiresharkFile, IDisposable, IEnumerable<WiresharkFilePacket>
{
....
}
我的收藏:
public ObservableCollection<WiresharkFile> wiresharkFiles { get; set; }
此时,我的所有
WiresharkFile
(Libpcap
type)属性都在更改,因此我想知道我需要在哪里定义此inotifPropertyChanged
如果xaml绑定到WiresharkFile的属性,则WiresharkFile必须实现inotifPropertyChanged,否则将导致内存泄漏(). 如果绑定仅在Libpcap类上定义,那么Libpcap必须实现INotifyPropertyChanged接口。在我的项目中,我创建了INotifyPropertyChanged接口的一个基本实现,然后每个基本模型和基本视图模型都从该实现继承。以下是一些基本代码:
1.基本实施:
public class BaseObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
{
var propName = ((MemberExpression)raiser.Body).Member.Name;
OnPropertyChanged(propName);
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(name);
return true;
}
return false;
}
}
关于这一点,与IIan的答案相同,但对于C#8和.Net Framework 4.8 一,。基本模型 三,。如何使用
UI是否需要知道这些更改?是的,我想更新我的UI。为什么创建此BaseObserveObject,为什么不使用INotifyPropertyChanged?因为它允许您使用OnPropertyChanged()代码>在派生类中,而不需要包含其代码。这是干(不要重复你自己)的编码原则。您可能有几十个类都需要更改INotifyPropertyChanged
,而不是在每个类中编写相同的onPropertyHagned()
,您只需编写一次,然后在12个类中执行:BaseObservableObject
。因此,只需从我的基类(WiresharkFile)中的BaseObservableObject派生即可并为每个更改的属性添加OnPropertyChanged()?(无需这样做:OnPropertyChanged(“property name”)?顺便说一句,我还有静态属性:是否可以为静态属性添加OnPropertyChanged?@davidhol关于第一个问题“那么就……”;是的,在使用4.5.Net的情况下,如果您使用的是4.0 dot.Net版本,则仍然必须使用旧方法(OnPropertyChanged(“Propert name”))或OnPropertyChanged(()=>Propert name))。关于最后一个问题,这里有几个链接,解释了如何绑定到static;但是请记住关于内存泄漏的问题。
wiresahrkFile.Sendpackets();
public class BaseObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
{
var propName = ((MemberExpression)raiser.Body).Member.Name;
OnPropertyChanged(propName);
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(name);
return true;
}
return false;
}
}
public abstract class WiresharkFile:BaseObservableObject
{
private string _fileName;
private int _packets;
private int _packetsSent;
private string _duration;
public int Packets
{
get { return _packets; }
set
{
_packets = value;
OnPropertyChanged();
}
}
public int PacketsSent
{
get { return _packetsSent; }
set
{
_packetsSent = value;
OnPropertyChanged();
}
}
}
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
{
string propName = ((MemberExpression)raiser?.Body).Member.Name;
OnPropertyChanged(propName);
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(name);
return true;
}
return false;
}
}
public class Current : ObservableObject
{
private string _status;
public Current()
{
Status = "Not Connected";
}
public string Status
{
get { return _status; }
set
{
_status = value;
OnPropertyChanged(); // call this to update
}
}
}
<Label Content="{Binding Status}"/>