开发者

"Single binding" works but not MultipleBinding with same parameters

Im using Bindings to change Style on a button. To be able to do this Ive found that I need to use MultipleBinding. But for some reason this doesnt work.

Here is the code in my UserControl (which inherits from a 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>

But this works great:

  <TextBlock Text="{Binding ElementName=mySelf, Path=HealthStatus}" />

I get this warning in the Output window during runtime:

System.Windows.Data Warning: 40 : BindingExpression path error: 'HealthStatus' property not found on 'object' ''MyLayoutViewModel' (HashCode=3696098)'. BindingExpression:Path=HealthStatus; DataItem='MyLayoutViewModel' (HashCode=3696098); target element is 'Button' (Name='Component'); target property is 'Style' (type 'Style')

Why cant HealthStatus be found in the MultipleBinding when it is obviously there?

I dont include the code for the converter since it doesnt seem to be the problem. HealthStatus is declared as enum but since it is working for the "singlebinding" and the error-message only says it cant find it I dont think thats the problem either.

Thanx!

Added:

This is my Converter:

  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();
    }
  } 

and the styles are declared in a resourcedictionary:

  <Style x:Key="WhiteStyle" TargetType="Button">

HealthStatus is declare in my UcBase class that I use as a base class for my 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); }
    }


The two bindings you showed do different things.

<TextBlock Text="{Binding ElementName=mySelf, Path=HealthStatus}" />

Looks for a property "HealthStatus" on the control "mySelf"

While

    <MultiBinding Converter="{StaticResource styleConverter}">
      <MultiBinding.Bindings>
        <Binding ElementName="mySelf"/>
        <Binding Path="HealthStatus"/>
      </MultiBinding.Bindings>
    </MultiBinding>

Looks for 2 values: "mySelf" which is a Control and the "HealthStatus" property. Since you didn't clarify where to look for the last one, it will look in the DataContext for a property called HealthStatus!

Then once it got those 2 values, it will convert them using your IMultiValueConverter, that should return a Style

Now i'm just guessing at what you really want to achieve, but if you want to bind to the "HealthStatus" property, you will need to change the MultiBinding to:

    <MultiBinding Converter="{StaticResource styleConverter}">
      <MultiBinding.Bindings>
        <Binding ElementName="mySelf"/>
        <Binding Path="HealthStatus" ElementName="mySelf"/>
      </MultiBinding.Bindings>
    </MultiBinding>

EDIT: To answer the comment, you couldn't do this with a simple converter, because you need to know the UserControl where the style you want to apply resides, otherwise how will you find it?

I guess in your converter you decide which style to use based on "HealthStatus" then you use the FindResource("Resource_Name") method to fetch it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜