“单个绑定”有效但不具有相同参数的MultipleBinding

时间:2011-10-04 11:14:52

标签: wpf

我使用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); }
    }

1 个答案:

答案 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”)方法来获取它。