我使用Bindings来改变按钮上的Style。为了能够做到这一点,我发现我需要使用MultipleBinding。但由于某些原因,这不起作用。
以下是我的UserControl中的代码(继承自uc-base-class):
<CtrlLib:UcBaseCounter
...
x:Name="mySelf">
<CtrlLib:UcBaseCounter.Resources>
<ResourceDictionary>
...
<CtrlLib:StyleConverter x:Key="styleConverter" />
</ResourceDictionary>
</CtrlLib:UcBaseCounter.Resources>
<Grid Margin="2">
<Button Click="Ctrl_Click">
<Button.Style>
<MultiBinding Converter="{StaticResource styleConverter}">
<MultiBinding.Bindings>
<Binding ElementName="mySelf"/>
<Binding Path="HealthStatus"/>
</MultiBinding.Bindings>
</MultiBinding>
</Button.Style>
但这很有效:
<TextBlock Text="{Binding ElementName=mySelf, Path=HealthStatus}" />
我在运行时在输出窗口中收到此警告:
System.Windows.Data警告:40:BindingExpression路径错误:'object'''MyLayoutViewModel'(HashCode = 3696098)'找不到'HealthStatus'属性。 BindingExpression:路径= HealthStatus; DataItem ='MyLayoutViewModel'(HashCode = 3696098); target元素是'Button'(Name ='Component'); target属性为'Style'(类型'Style')
为什么在显然存在多重绑定时才能找到HealthStatus?
我不包括转换器的代码,因为它似乎不是问题。 HealthStatus被声明为枚举,但因为它正在为“单绑定”工作,而错误消息只是说它找不到它我也不认为这就是问题。
感谢名单!
这是我的转换器:
public class StyleConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
FrameworkElement targetElement = values[0] as FrameworkElement;
HealthStatus.Statuses status;
status = ((UcBase)targetElement).HealthStatus;
Style newStyle;
switch (status)
{
case HealthStatus.Statuses.Error:
newStyle = (Style)targetElement.TryFindResource("RedStyle");
return newStyle;
...
}
return (Style)targetElement.TryFindResource("WhiteStyle");
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
并且样式在resourcedictionary中声明:
<Style x:Key="WhiteStyle" TargetType="Button">
HealthStatus在我的UcBase类中声明我用作UserControls的基类:
public class UcBase : UserControl
{
public static readonly DependencyProperty HealthStatusProperty = DependencyProperty.Register("HealthStatus", typeof(HealthStatus.Statuses), typeof(UcBase));
public HealthStatus.Statuses HealthStatus
{
get { return (HealthStatus.Statuses)this.GetValue(HealthStatusProperty); }
set { this.SetValue(HealthStatusProperty, value); }
}
答案 0 :(得分:1)
你展示的两个绑定做了不同的事情。
<TextBlock Text="{Binding ElementName=mySelf, Path=HealthStatus}" />
在控件“mySelf”
上查找属性“HealthStatus”虽然
<MultiBinding Converter="{StaticResource styleConverter}">
<MultiBinding.Bindings>
<Binding ElementName="mySelf"/>
<Binding Path="HealthStatus"/>
</MultiBinding.Bindings>
</MultiBinding>
查找2个值:“mySelf”,这是 Control
和“HealthStatus”属性。
由于您没有说明在哪里查找最后一个,因此它将在DataContext中查找名为HealthStatus的属性!
然后,一旦获得这两个值,它将使用您的IMultiValueConverter转换它们,它应返回 Style
现在我只是猜测你真正想要实现的目标,但是如果要绑定到“HealthStatus”属性,则需要将MultiBinding更改为:
<MultiBinding Converter="{StaticResource styleConverter}">
<MultiBinding.Bindings>
<Binding ElementName="mySelf"/>
<Binding Path="HealthStatus" ElementName="mySelf"/>
</MultiBinding.Bindings>
</MultiBinding>
编辑:要回答评论,您无法使用简单的转换器执行此操作,因为您需要知道要应用的样式所在的UserControl,否则您将如何找到它?
我想在您的转换器中根据“HealthStatus”决定使用哪种样式,然后使用FindResource(“Resource_Name”)方法来获取它。