Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF PropertyChange不级联-设置一个自定义类dependencyproperty的动画会更改其他属性-PropertyChange仅对第一个类激发_C#_Wpf_Animation_Binding_Inotifypropertychanged - Fatal编程技术网

C# WPF PropertyChange不级联-设置一个自定义类dependencyproperty的动画会更改其他属性-PropertyChange仅对第一个类激发

C# WPF PropertyChange不级联-设置一个自定义类dependencyproperty的动画会更改其他属性-PropertyChange仅对第一个类激发,c#,wpf,animation,binding,inotifypropertychanged,C#,Wpf,Animation,Binding,Inotifypropertychanged,非常简单,这是我的问题:(底部的解决方案) 我有一个自定义类,继承Animatable和INotifyPropertyChange,其中包含一个DependencyProperty(我设置动画,比如从1到10)和一个额外属性(我想从XAML使用绑定): 当我将GUI元素绑定到属性时,我实际设置了动画(AnimateValue),一切都按预期工作-当我将GUI元素绑定到相关属性(GuiValue)时,什么都没有发生。我猜更改的事件没有达到该属性,但我真的不知道如何解决该问题。有什么建议吗 非常感谢

非常简单,这是我的问题:(底部的解决方案)

我有一个自定义类,继承Animatable和INotifyPropertyChange,其中包含一个DependencyProperty(我设置动画,比如从1到10)和一个额外属性(我想从XAML使用绑定):

当我将GUI元素绑定到属性时,我实际设置了动画(AnimateValue),一切都按预期工作-当我将GUI元素绑定到相关属性(GuiValue)时,什么都没有发生。我猜更改的事件没有达到该属性,但我真的不知道如何解决该问题。有什么建议吗

非常感谢您的帮助

编辑:感谢Adam Sills和Kai Wang的两个回复,我真蠢,漏掉了第二个OnProperty更改电话,但是我以前尝试过,但没有成功。为了调试,我在AnimateValue.set函数中放了一条writeline,瞧,它根本没有执行

我还尝试将getter更改为始终返回20-无更改!:-o动画似乎完全跳过了属性get和set,并对底层dependencyproperty设置动画和读取。。。还是我误解了?我使用的动画代码是:

DoubleAnimation da = new DoubleAnimation (1, 10, new Duration(TimeSpan.FromSeconds(3)));
myClassInstance.BeginAnimation(MyClass.AnimateValueProperty, da);
嗯。。。在这里编写代码之后,似乎不使用setter是非常合理的(尽管我真的希望如此!)-但是,基本问题仍然存在,我仍然不明白为什么不使用getter

Edit2:解决方案

正如下面所建议的,我不能对连接到DependencyProperty的属性使用InotifyProperty更改-动画和XAML在内部使用DependencyProperty,而根本不使用getter和setter

因此-PropertyChangedCallback在更改时通知其他人,强制evalueCallback“修复”数据。也可以验证数据,所有这些都是在DependencyProperty构造函数中完成的。谢谢大家

谢谢


/维克托我不知道我是否明白你的意思。但看看这是否有帮助

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

我不知道我是否明白你的意思。但看看这是否有帮助

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

通过设置AnimateValue的值,可以告诉WPF它已更改。但您永远不会告诉WPF GUI值已更改。如果您不告诉WPF数据绑定框架,那么它如何知道GUI值已经更改

更新AnimateValue并发出更改通知时(由于它是一个依赖项属性,因此不需要更改),还需要发出关于GUI值的通知,因为它依赖于AnimateValue,但在属性内部手动计算

基本上只需添加

OnPropertyChanged(new PropertyChangedEventArgs("GuiValue"));
到AnimateValue集块

更新:

根据您的新编辑,如果通过XAML进行属性设置,则不会调用依赖项属性的getter/setter,而是直接通过GetValue/SetValue完成


如果需要对更改进行本地响应,请重写OnPropertyChanged或在DependencyProperty内提供更改回调。通过设置AnimateValue的值注册,可以告诉WPF它已更改。但您永远不会告诉WPF GUI值已更改。如果您不告诉WPF数据绑定框架,那么它如何知道GUI值已经更改

更新AnimateValue并发出更改通知时(由于它是一个依赖项属性,因此不需要更改),还需要发出关于GUI值的通知,因为它依赖于AnimateValue,但在属性内部手动计算

基本上只需添加

OnPropertyChanged(new PropertyChangedEventArgs("GuiValue"));
到AnimateValue集块

更新:

根据您的新编辑,如果通过XAML进行属性设置,则不会调用依赖项属性的getter/setter,而是直接通过GetValue/SetValue完成


如果您需要在本地响应更改,请重写OnPropertyChanged或在DependencyProperty内提供更改回调。Register

这里有一个属性更改NotiAction模式,用于依赖属性

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

我有一种感觉,但不完全确定,你可能需要做的是强制其他价值观

这里是一个属性更改的NotiAction模式,用于依赖项属性

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

我有一种感觉,但不完全确定,你可能需要做的是强制其他价值观

如果对象是从依赖项对象派生的,则不能使用INotifyPropertyChanged,因为绑定体系结构将仅使用依赖项属性重新注册来使用绑定

为此,您需要只读依赖项属性,我已解释如下

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

如果对象是从依赖项对象派生的,则不能使用INotifyPropertyChanged,因为绑定体系结构将仅使用依赖项属性重新注册来使用绑定

为此,您需要只读依赖项属性,我已解释如下

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

谢谢你的指点,当然应该在那里!我曾经尝试过,但没有任何运气,请编辑上面的详细信息。谢谢你的指针,当然应该在那里!我以前也尝试过,但没有任何运气,请编辑上面的详细信息。感谢指针,OnPropertyChanged当然也应该在那里。不过我以前也试过,请编辑上面的详细信息。感谢指针,OnPropertyChanged当然也应该在那里。我以前也尝试过,请编辑上面的详细信息。我已经更新了我的代码,请看一看,我认为你需要只读依赖属性,我在我的答案中给了你一个示例。谢谢,回答得很好。我也问你-为什么是“只读”?我已经更新了我的代码,请看一看,我认为你需要只读依赖属性,我在我的a中给了你一个示例