【发布时间】:2012-12-19 16:10:32
【问题描述】:
我在 EventTrigger 中有以下绑定:
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="PreviewMouseDown">
<SoundPlayerAction Source="{Binding Path=SoundFile, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource soundFileConverter}}" />
</EventTrigger>
...
过程如下:自定义控件(即它的模板)有一个名为SoundFile的属性,一个枚举类型。在转换器中,此枚举值应转换为 Uri 以将其传递给 SoundPlayerAction。
问题是:无论如何都没有调用转换器。输出窗口出现以下错误:
找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。 绑定表达式:路径=声音文件;数据项=空;目标元素是“SoundPlayerAction” 哈希码=46763000);目标属性是“源”(类型“Uri”)
绑定表达式有什么问题?
编辑:
为了更好地概览,这里是控件的整个模板:
<Style TargetType="{x:Type controls:Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:Button}">
<Border Name="Border"
Background="{TemplateBinding Background}"
BorderBrush="Transparent"
BorderThickness="0">
<Border.CornerRadius>
<MultiBinding Converter="{StaticResource areaCornerRadiusConverter}">
<MultiBinding.Bindings>
<Binding Path="RoundType" RelativeSource="{RelativeSource TemplatedParent}" />
<Binding Path="ActualHeight" RelativeSource="{RelativeSource TemplatedParent}" />
</MultiBinding.Bindings>
</MultiBinding>
</Border.CornerRadius>
<TextBlock Margin="{Binding Path=RoundType,
RelativeSource={RelativeSource TemplatedParent},
Converter={StaticResource buttonMarginConverter}}"
FontSize="{TemplateBinding FontSize}"
Style="{StaticResource innerTextBlock}"
Text="{TemplateBinding Text}" />
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="PreviewMouseDown">
<SoundPlayerAction Source="{Binding Path=SoundFile, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource soundFileConverter}}" />
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
编辑 2:
我尝试了另一种方法:将 SoundPlayerAction 的 name 属性设置为 PART_SoundPlayerAction 并使用 GetTemplateChild 从代码隐藏中检索它。但是 GetTemplateChild 总是返回 null。这真的很烦人。似乎没有任何效果...
编辑 3:
现在,随着 Blachshma 的回答,我知道在控件初始化期间调用了转换器。但不是在属性发生变化时。此外,转换器返回的值不会作为 Source 应用于 SoundPlayerAction。
我实现了 BindingProxy:
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion
public SoundFile Data
{
get { return (SoundFile)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(SoundFile), typeof(BindingProxy), new UIPropertyMetadata(SoundFile.None));
}
我将Path=Data.SoundFile 更改为Path=Data。有错吗?
编辑 4:
使用 MakeSoundCommand 的解决方案运行良好。非常感谢 Blachshma。
【问题讨论】:
-
SoundPlayerAction是wpf内置的类,看msdn:msdn.microsoft.com/en-us/library/…
标签: c# wpf xaml binding custom-controls