我使用,我不能编辑类,它有一个属性(一个布尔值),其中这将是很好当它改变时,我不能编辑属性获取或因为我从导入类设置予以通报。 DLL(我没有为代码)。
如何创建时的属性更改时触发的事件/功能?
额外
它不仅是它自己的类内变化,直接向潜在的私有变量。
如
private bool m_MyValue = false;
public bool MyValue
{
get { return m_MyValue; }
}
private void SomeFunction()
{
m_MyValue = true;
}
你不能,基本上......不是没有使用类似的调试器API注入在执行时的代码和修改原始库的IL(和我不建议任何的解决方案;除了别的可能违反该库的许可)。
基本上如果一个属性不支持通知,它不支持通知。 你应该找接近你的问题的不同方式。 (就民意调查工作,例如?)
你不能直接这样做[为乔恩斯基特说],除非它是虚拟的,你在一个位置拦截类的所有实例的创作,并有到影响propget子的真正“价值”支持字段没有变化。
蛮力的唯一途径,这是使用Mono.Cecil能或MS CCI仪器道具二传手一拉这个DimeCast上塞西尔 。 (或者PostSharp)
然而,这不会陷阱内部变化到背衬字段(如果有的话甚至是一个)。 (这就是为什么包装可能不会工作)。
更新:鉴于你的更新,你肯定是想诱使基础字段的变化,要做到这一点的唯一方法是使用PS / CCI /塞西尔和分析流量拦截所有字段更新。 总之,不是很可行。
可以说,这样做的唯一途径是创造某种“守望者”组成的,在一个单独的线程,他们的工作是阅读的时间间隔的财产,引发一个事件时,该属性的值发生变化运行。 当然,这个解决方案帆线程和同步的浑水。
在您的应用程序是单线程的,在对于该对象的假设,你干净的解决方案是使方法调用通过代理对象这个对象。 它会前和财产的状态后检查和它改变的情况下引发事件的工作。
下面是我在谈论的一个简单的例子:
public class SomeProxy
{
public SomeProxy(ExternalObject obj)
{
_obj = obj;
}
public event EventArgs PropertyChanged;
private bool _lastValue;
private ExternalObject _obj;
protected virtual void OnPropertyChanged()
{
if(PropertyChanged != null)
PropertyChanged();
}
protected virtual void PreMethodCall()
{
_lastValue = _obj.SomeProperty;
}
protected virtual void PostMethodCall()
{
if(_lastValue != _obj.SomeProperty)
OnPropertyChanged();
}
// Proxy method.
public SomeMethod(int arg)
{
PreMethodCall();
_obj.SomeMethod(arg); // Call actual method.
PostMethodCall();
}
}
很明显,你可以建立这种代理模式到合适的对象-你只需要知道, 所有的呼叫都经过代理,因为当你想到它是被引发的事件。
如前所述,(其需要最少改变代码和)的最直接的方法是使用AOP库如PostSharp。
然而,溶液可以使用传统的C#/。NET通过使用来实现依赖属性模式 ,throughtout WPF用于很大的影响。 我建议在这读了,并考虑为您的项目,实施这样的系统(或至少它的简化版本),如果不合适。
您需要创建一个包装DLL中的类的类,二传手属性中只是提高有使用普通方法的事件。
你可以从类继承和隐藏属性? 事情是这样的......
class MyClass : BaseClass
{
// hide base property.
public new bool MyProperty
{
get
{
return base.MyProperty;
}
set
{
base.MyProperty = value;
RaiseMyPropertyChangedEvent();
}
}
}
我认为,一个包装的Alex的想法是好的,但是,因为对你来说最重要的事情是,你知道该值在使用前改变了,你可以在通知干脆转移到吸气剂,规避内在价值变化的忧虑。 这样,你得到类似的东西投票而可靠:
class MyClass : BaseClass
{
//local value
private bool local;
//first access yet?
private bool accessed = false;
// Override base property.
public new bool MyProperty
{
get
{
if(!accessed)
{
// modify first-get case according to your taste, e.g.
local = base.MyProperty;
accessed = true;
RaiseMyPropertyChangedBeforeUseEvent();
}
else
{
if(local != base.MyProperty)
{
local = base.MyProperty;
RaiseMyPropertyChangedBeforeUseEvent();
}
}
return local;
}
set
{
base.MyProperty = value;
}
}
}
你可以试着继承它,使用它的孩子,而不是它。 重写属性的“设置”,因此引发事件。
编辑:...只有属性是在父类中的虚...