我正在尝试将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永远不会更新其Text。起初,我认为DownloadProgress属性不是DependencyProperty,但它是......根据MSDN。
解决方法是侦听DownloadProgressChanged事件并使用代码隐藏更新我的TextBlock,但这是我试图避免的。
任何意见都将受到高度赞赏。
最诚挚的问候,
基里尔
答案 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一起使用会有什么用。