代码之家  ›  专栏  ›  技术社区  ›  Kiril Stanoev

MediaElement:元素绑定到DownloadProgress

  •  1
  • Kiril Stanoev  · 技术社区  · 15 年前

    我正在尝试绑定 DownloadProgress 依赖属性 属于 MediaElement 文本块的文本。

    <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>
    

    不幸的是,文本块从不更新其文本。一开始,我以为 下载进度 属性不是DependencyProperty,但它是…根据MSDN。

    解决方法是监听downloadprogresschanged事件并使用代码隐藏更新我的文本块,但这是我试图避免的。

    如有任何意见,将不胜感激。

    谨致问候,

    基里尔

    1 回复  |  直到 15 年前
        1
  •  2
  •   Community CDub    8 年前

    我相信这是因为MediaElement上这些属性的更改事件的类型是RoutedEventHandler,而不是RoutedPropertyChangedEventHandler(就像滑块上的ValueChanged事件一样)。由于downloadprogress确实是一个dependencProperty,因此初始元素绑定工作正常,它永远不会收到任何类型的通知,即属性更改,因此它永远不会更新。

    这意味着您在某种程度上很难键入downloadprogresschanged事件。如果你 真的? 为了避免使用代码隐藏,我建议使用某种混合targetdtriggeration。仍然会有少量的代码,但它将在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事件触发器的操作调用,并将要更新的文本块作为目标。

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

    我不确定这对你来说是否比直接用代码连接更干净,但我个人更喜欢它。我唯一能想到的另一种解决方案是 described here 它可以实现inotifypropertychanged并处理通知,但我不完全确定将其用于medialelement涉及到什么。