WPF的PropertyChange不级联 - 动画一个自定义类的DependencyProperty改变其他属性 - 的PropertyChange只为第一火灾

StackOverflow https://stackoverflow.com/questions/1452379

非常简化的,这是我的问题:(在底部溶液)

我有一个自定义类,继承设置动画和INotifyPropertyChange,含有一个的DependencyProperty(我动画,说从1到10)和一个额外的属性(我想从XAML与使用的结合):

MyClass : Animatable, INotifyPropertyChanged {

    public static DependencyProperty AnimateValueProperty = DependencyProperty.Register(
      "AnimateValue",
      typeof(double),
      typeof(MyClass)
     );

    public double AnimateValue {
        get { return (double)GetValue(AnimateValueProperty); }
        set {
                SetValue(AnimateValueProperty, value);
                OnPropertyChanged(new PropertyChangedEventArgs("AnimateValue"));
                OnPropertyChanged(new PropertyChangedEventArgs("GuiValue")); //Added in edit
            }
        }
    }

    public double GuiValue {
        get { 
            return AnimateValue + 10; 
            //More fancy stuff happening in the real class...
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {
        if (PropertyChanged != null) {
            PropertyChanged(this, e);
        }
    }

    protected override Freezable CreateInstanceCore() {
        return new MyClass();
    }
}

当我绑定的GUI元素我其实动画属性(AnimateValue)一切正常 - 当我的GUI元素绑定到相关的属性(GuiValue)没有任何反应。我想这改变的事件没有达到这个属性,但我真的不知道该如何解决这个问题。任何指针?

任何帮助是非常感谢!

编辑:谢谢你从亚当·西尔斯和王凯两个答复,我愚蠢的离开了第二OnPropertyChange电话,但我已尝试之前,它没有工作。为了调试,我把的WriteLine在AnimateValue.set功能看哪! - 它并不会在所有执行

我也试图改变getter方法总是返回20 - 没有任何变化! :-o好像动画完全跳过属性的get和set和动画,并读取底层的DependencyProperty ......还是我误会了?我用动画的代码是:

DoubleAnimation da = new DoubleAnimation (1, 10, new Duration(TimeSpan.FromSeconds(3)));
myClassInstance.BeginAnimation(MyClass.AnimateValueProperty, da);

嗯......这里编写代码后似乎很合理的设置器不使用(虽然我真的很喜欢它的!) - 但尽管如此,基本的问题,代表,我仍然不明白为什么吸气剂不使用!

EDIT2:<!强> 解决方案

如所建议的下面我不可能使用INotifyPropertyChange用于连接到的DependencyProperty属性 - 动画和XAML使用DepencencyProperty内部和完全不使用getter和setter。

因此 - PropertyChangedCallback到变化通知他人,CoerceValueCallback“修理”的数据。也可以验证数据,所有这一切都是在构造的DependencyProperty完成。谢谢大家!

谢谢!

/维克多

有帮助吗?

解决方案

这里是用于与依赖属性使用属性更改notifaction图案

  public Boolean PasswordBoxVisible {
     get { return (Boolean)GetValue(PasswordBoxVisibleProperty); }
     set { SetValue(PasswordBoxVisibleProperty, value); }
  }

  public static readonly DependencyProperty PasswordBoxVisibleProperty =
      DependencyProperty.Register("PasswordBoxVisible", typeof(Boolean), typeof(UserControl), new UIPropertyMetadata(false, new PropertyChangedCallback(PropChanged)));

  //this method is called when the dp is changed
  static void PropChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) {
       UserControl userControl = o as UserControl;
       //now you can use this to call some methods, raise other value changed etc, in this case OtherProperty.
       userControl.NotifyPropertyChanged("OtherProperty");
  }

我有一种感觉,但我不能完全肯定,那你可能需要做的是迫使其他值。 看看这篇文章

其他提示

通过设定AnimateValue的值,你告诉WPF它已经改变了。但你永远不会告知GuiValue已经改变了WPF。 WPF的数据绑定框架应该是怎样知道GuiValue当你不知道它有什么改变?

当你更新AnimateValue,提高变更的通知(其本身是没有必要的,因为它是一个依赖属性),你也需要筹集约GuiValue通知,是因为它是依赖于AnimateValue但手动计算内属性。

基本上只是添加

OnPropertyChanged(new PropertyChangedEventArgs("GuiValue"));

到AnimateValue设定的块。

<强>更新

根据新修改

,如果做你的财产通过XAML中,吸气设定/依赖项属性的setter方法不会被调用,这一切都是通过做的GetValue /直接的SetValue

如果您需要响应局部地变化,重写OnPropertyChanged或提供内部DependencyProperty.Register变化回调

我不知道如果我明白你的意思。但是,看看是否有所帮助。

    public double AnimateValue {
    get { return (double)GetValue(AnimateValueProperty); }
    set {
            SetValue(AnimateValueProperty, value);
            OnPropertyChanged(new PropertyChangedEventArgs("AnimateValue"));
            OnPropertyChanged(new PropertyChangedEventArgs("GuiValue "));
        }
    }
}

如果你的对象是从依赖对象派生那么你可以不使用INotifyPropertyChanged的,因为绑定体系结构将只使用依赖项属性Resgistration才能使用绑定。

有关这一点,你需要的只读依赖项属性我已经解释如下。

public static DependencyProperty AnimateValueProperty = 
   DependencyProperty.Register(
      "AnimateValue",
      typeof(double),
      typeof(MyClass)
   );

 // This is for the Readonly GuiValueKey property
 public static DependencyPropertyKey GuiValueKey = 
     DependencyProperty.RegisterReadOnly (
     "GuiValue",
      typeof(double),
      typeof(MyClass),
      new UIPropertyMetadata(0.0)
);

public double AnimateValue {
    get { return (double)GetValue(AnimateValueProperty); }
    set {
            SetValue(AnimateValueProperty, value);
            // Following statement update GuiValue wherever it
            // is binded
            this.SetValue(GuiValueKey,value + 10);
        }
    }
}

// you dont even need following line...
// but its good to have it..
public double GuiValue {
    get { 
        return (double)this.GetValue(GuiValueKey); 
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top