SetValue打破了来自源的后续更新

时间:2010-09-06 21:27:48

标签: c# wpf

我遇到了一段代码的问题,这些代码开始让我失去理智。我在WPF中有一个基类,声明了DependencyProperty:

public partial class AudioTimeControlBase : UserControl
{
    public static readonly DependencyProperty PlaybackPositionProperty = DependencyProperty.RegisterAttached(
        "PlaybackPosition", typeof(TimeSpan), typeof(AudioTimeControlBase),
        new FrameworkPropertyMetadata(TimeSpan.Zero, 
            FrameworkPropertyMetadataOptions.Inherits | 
            FrameworkPropertyMetadataOptions.AffectsRender |
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
            OnPlaybackPositionChanged, CoercePlaybackPosition));


    public TimeSpan PlaybackPosition
    {
        get { return (TimeSpan)this.GetValue(PlaybackPositionProperty); }
        set { this.SetValue(PlaybackPositionProperty, value); }
    }

    private static void OnPlaybackPositionChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        AudioTimeControlBase control = sender as AudioTimeControlBase;
        if (control != null)
            control.OnPlaybackPositionChanged(e);
    }

    protected virtual void OnPlaybackPositionChanged(DependencyPropertyChangedEventArgs e)
    {
    }

    private static object CoercePlaybackPosition(DependencyObject d, object value)
    {
        TimeSpan t = (TimeSpan)value;
        if(t < TimeSpan.Zero)
            return TimeSpan.Zero;
        return t;
    }

}

然后是派生控件:

public partial class WaveViewerControl : AudioTimeControlBase
{
    public WaveViewerControl()
    {
        InitializeComponent();
    }

    void playbackControl_PositionChanged(object sender, EventArgs e)
    {
        PlaybackPosition = ConvertFromPosition(playbackControl.Position);
    }
 }

我已经拿出了相当多的东西,但我真的认为我已经把这些有问题的东西隔离开了。问题是当playbackControl_PositionChanged发生时(由于用户操作),它会中断(以前工作)与PlaybackPositionProperty的绑定,并且控件不会收到后续更新。如果任何人有任何想法或线索,我将永远感激。谢谢!

UPDATE :我意识到我遗漏了一些潜在的关键信息 - 这个控件没有在我的XMAL中直接表示,而是以编程方式添加到父控件中。但是,根据“Inhert”选项,正确继承了该父项的绑定。直到SetValue调用它们才显然被覆盖。这是否表明继承属性不支持双向绑定?

2 个答案:

答案 0 :(得分:1)

根据WPF Unleashed,设置值会直接删除绑定。 (第261页)所以您所描述的是按设计

答案 1 :(得分:0)

如果在设置为非双向或单向源的绑定表达式的属性上调用SetValue,则它将使用新值替换绑定表达式。您将PlaybackPositionProperty设置为默认绑定双向,但仍可以手动将绑定设置为Mode=OneWay

检查正在使用WaveViewerControl的XAML,并查看PlaybackPosition上的绑定是否为Mode=OneWay。您还可以通过在事件处理程序中调用BindingOperations.GetBinding(this, PlaybackPositionProperty).Mode来在运行时检查绑定。


根据您的更新,是的,这是正确的行为。您无法更新由属性值继承设置的双向绑定表达式。您正在设置本地值,该值将覆盖继承的值。见Dependency Property Value Precedence