在属性触发事件/功能? (C#)(Firing an event / function on a

2019-07-31 13:01发布

我使用,我不能编辑类,它有一个属性(一个布尔值),其中这将是很好当它改变时,我不能编辑属性获取或因为我从导入类设置予以通报。 DLL(我没有为代码)。

如何创建时的属性更改时触发的事件/功能?

额外
它不仅是它自己的类内变化,直接向潜在的私有变量。

private bool m_MyValue = false;

public bool MyValue
  {
  get { return m_MyValue; }
  }

private void SomeFunction()
  {
  m_MyValue = true;
  }

Answer 1:

你不能,基本上......不是没有使用类似的调试器API注入在执行时的代码和修改原始库的IL(和我不建议任何的解决方案;除了别的可能违反该库的许可)。

基本上如果一个属性不支持通知,它不支持通知。 你应该找接近你的问题的不同方式。 (就民意调查工作,例如?)



Answer 2:

你不能直接这样做[为乔恩斯基特说],除非它是虚拟的,你在一个位置拦截类的所有实例的创作,并有到影响propget子的真正“价值”支持字段没有变化。

蛮力的唯一途径,这是使用Mono.Cecil能或MS CCI仪器道具二传手一拉这个DimeCast上塞西尔 。 (或者PostSharp)

然而,这不会陷阱内部变化到背衬字段(如果有的话甚至是一个)。 (这就是为什么包装可能不会工作)。

更新:鉴于你的更新,你肯定是想诱使基础字段的变化,要做到这一点的唯一方法是使用PS / CCI /塞西尔和分析流量拦截所有字段更新。 总之,不是很可行。



Answer 3:

可以说,这样做的唯一途径是创造某种“守望者”组成的,在一个单独的线程,他们的工作是阅读的时间间隔的财产,引发一个事件时,该属性的值发生变化运行。 当然,这个解决方案帆线程和同步的浑水。

在您的应用程序是单线程的,在对于该对象的假设,你干净的解决方案是使方法调用通过代理对象这个对象。 它会前和财产的状态后检查和它改变的情况下引发事件的工作。

下面是我在谈论的一个简单的例子:

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();
    }
}

很明显,你可以建立这种代理模式到合适的对象-你只需要知道, 所有的呼叫都经过代理,因为当你想到它是被引发的事件。



Answer 4:

如前所述,(其需要最少改变代码和)的最直接的方法是使用AOP库如PostSharp。

然而,溶液可以使用传统的C#/。NET通过使用来实现依赖属性模式 ,throughtout WPF用于很大的影响。 我建议在这读了,并考虑为您的项目,实施这样的系统(或至少它的简化版本),如果不合适。



Answer 5:

您需要创建一个包装DLL中的类的类,二传手属性中只是提高有使用普通方法的事件。



Answer 6:

你可以从类继承和隐藏属性? 事情是这样的......

class MyClass : BaseClass
{
    // hide base property.
    public new bool MyProperty
    {
        get
        {
            return base.MyProperty;
        }

        set
        {
            base.MyProperty = value;
            RaiseMyPropertyChangedEvent();
        }
    }
}


Answer 7:

我认为,一个包装的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;
        }
    }
}


Answer 8:

你可以试着继承它,使用它的孩子,而不是它。 重写属性的“设置”,因此引发事件。

编辑:...只有属性是在父类中的虚...



文章来源: Firing an event / function on a property? (C#)