MediaElement:元素绑定到DownloadProgress

时间:2010-02-03 08:53:05

标签: silverlight mediaelement

我正在尝试将DownloadProgressMediaElement 依赖属性绑定到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永远不会更新其Text。起初,我认为DownloadProgress属性不是DependencyProperty,但它是......根据MSDN。

解决方法是侦听DownloadProgressChanged事件并使用代码隐藏更新我的TextBlock,但这是我试图避免的。

任何意见都将受到高度赞赏。

最诚挚的问候,

基里尔

1 个答案:

答案 0 :(得分:2)

我相信这是因为MediaElement上这些属性的更改事件是RoutedEventHandler类型而不是RoutedPropertyChangedEventHandler类型(就像Slider那样的ValueChanged事件)。由于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");
    }
}

然后,您将调用此作为XAML中DownloadProgressChanged EventTrigger的操作,并将要更新的TextBlock作为目标。

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

我不确定这对你来说是否比在代码隐藏中直接连接更清洁,但我个人更喜欢它。我能想到的唯一其他解决方案是某种BindingConduit助手described here可以实现INotifyPropertyChanged并处理通知,但我不完全确定将其与MediaElement一起使用会有什么用。