SetValue, ломая последующие обновления из источника - PullRequest
0 голосов
/ 07 сентября 2010

У меня проблема с фрагментом кода, который начинает выводить меня из себя. У меня есть базовый класс в 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);
    }
 }

Я вытащил изрядное количество вещей, но я действительно думаю, что выделил оскорбительные части этого. Проблема заключается в том, что, когда происходит воспроизведениеControl_PositionChanged (в результате действий пользователя), оно нарушает (ранее работающую) привязку к PlaybackPositionProperty и элемент управления не получает последующих обновлений. Если у кого-то есть какие-либо мысли или наводки, я буду вечно благодарен. Спасибо!

ОБНОВЛЕНИЕ : я понимаю, что исключил из этого некоторую потенциально важную информацию - этот элемент управления не представлен непосредственно в моем XMAL, но программно добавлен в родительский элемент управления. Однако, согласно опции «Inhert», привязки этого родителя правильно наследуются. Только после вызова SetValue они явно переопределяются. Означает ли это, что двустороннее связывание не поддерживается унаследованными свойствами?

Ответы [ 2 ]

1 голос
/ 07 сентября 2010

Согласно WPF Unleashed, установка значения напрямую удаляет привязку.(стр. 261), так что вы описали по схеме .

0 голосов
/ 07 сентября 2010

Если вы вызовите SetValue для свойства, для которого установлено выражение привязки, которое не является двусторонним или односторонним по отношению к источнику, то оно заменит выражение привязки новым значением.По умолчанию для PlaybackPositionProperty установлено двухстороннее связывание, но для Binding по-прежнему можно вручную установить значение Mode=OneWay.

Проверьте XAML, где используется WaveViewerControl, и посмотрите, имеет ли привязка для PlaybackPosition значение Mode=OneWay.Вы также можете проверить привязку во время выполнения, вызвав BindingOperations.GetBinding(this, PlaybackPositionProperty).Mode в вашем обработчике событий.


На основании вашего обновления, да, это правильное поведение.Вы не можете обновить выражение двусторонней привязки, которое устанавливается наследованием значения свойства.Вы устанавливаете локальное значение, которое переопределит унаследованное значение.См. Значение свойства зависимости Приоритет .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...