1

我正在尝试将 MediaElement 的 DownloadProgress 依赖属性绑定到 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,但这是我试图避免的事情。

任何意见将不胜感激。

此致,

基里尔

4

1 回答 1

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 帮助器,如此处所述,它可以实现 INotifyPropertyChanged 并处理通知,但我不完全确定将它与 MediaElement 一起使用会涉及什么。

于 2010-02-03T19:20:56.780 回答