MediaElement: привязка элемента к DownloadProgress - PullRequest
1 голос
/ 03 февраля 2010

Я пытаюсь выполнить очень простой сценарий привязки DownloadProgress свойства зависимости из MediaElement к тексту TextBlock.

<StackPanel>
    <MediaElement x:Name="mediaElement1" Width="500" Height="500" Source="http://ecn.channel9.msdn.com/o9/pdc09/wmv/CL20.wmv" AutoPlay="True" />
    <TextBlock Text="{Binding DownloadProgress, ElementName=mediaElement1, Mode=OneWay}" />
</StackPanel>

К сожалению, TextBlock никогда не обновляет свой текст. Сначала я подумал, что свойство DownloadProgress не является DependencyProperty, но оно ... согласно MSDN.

Обходной путь - прослушать событие DownloadProgressChanged и обновить мой TextBlock с помощью кода, но я стараюсь избегать этого.

Любые комментарии будут высоко оценены.

С наилучшими пожеланиями,

Кирил

1 Ответ

2 голосов
/ 03 февраля 2010

Я полагаю, что это потому, что события изменения для этих свойств в MediaElement имеют тип RoutedEventHandler вместо типа RoutedPropertyChangedEventHandler (как событие ValueChanged для чего-то вроде Slider). Начальная привязка элемента работает нормально, так как DownloadProgress действительно является DependencyProperty, просто никогда не получает никаких уведомлений об изменении свойства, поэтому оно никогда не обновится.

Это означает, что вы в какой-то степени застряли при отключении события DownloadProgressChanged. Если бы вы действительно хотели избежать использования выделенного кода, я бы предложил какое-то действие Blend TargettedTriggerAction. Там все еще будет небольшой кусочек кода, но он будет декларативно размечен в XAML, и, по крайней мере, он будет многократно использоваться и не входит в ваш код.

Нечто подобное может сработать (здесь я также занимаюсь преобразованием в% и десятичным форматированием):

[TypeConstraint(typeof(MediaElement))]
public class UpdateDownloadProgressBehavior : TargetedTriggerAction<TextBlock>
{
    protected override void Invoke(object parameter)
    {
        MediaElement mediaElement = (MediaElement)this.AssociatedObject;
        this.Target.Text = (mediaElement.DownloadProgress * 100).ToString("0.0");
    }
}

Затем вы вызываете это как действие для DownloadProgressChanged EventTrigger в вашем XAML и передаете TextBlock, который вы хотите обновить, в качестве цели.

   <MediaElement x:Name="MyMediaElement">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="DownloadProgressChanged">
                <local:UpdateDownloadProgressBehavior TargetName="MyTextBlock"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </MediaElement>

Я не уверен, кажется ли вам это чище, чем подключать его непосредственно в коде, но лично мне это нравится немного лучше. Единственное другое решение, которое я могу придумать, - это какой-то вспомогательный метод BindingConduit, например, , описанный здесь , который может реализовывать INotifyPropertyChanged и обрабатывать уведомления, но я не совсем уверен, что связано с использованием этого с MediaElement.

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