multiple binding to IsEnable
Asked Answered
L

3

9

I need to bind a TextBox that meets two criteria:

  • IsEnabled if Text.Length > 0
  • IsEnabled if user.IsEnabled

Where user.IsEnabled is pulled from a data source. I was wondering if anyone had a easy method for doing this.

Here is the XAML:

<ContentControl IsEnabled="{Binding Path=Enabled, Source={StaticResource UserInfo}}"> 
    <TextBox DataContext="{DynamicResource UserInfo}" Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding Path=Text, RelativeSource={RelativeSource Self}, Converter={StaticResource LengthToBool}}"/> 
</ContentControl>
Liebman answered 6/9, 2012 at 19:36 Comment(1)
How do you want these two properties combined? If both are true or if one is true?Aegis
A
6

Since you only need a logical OR, you just need two Triggers to your each of the properties.

Try this XAML:

<StackPanel>
        <StackPanel.Resources>
            <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=InputText, Path=Text}" Value="" >
                        <Setter Property="IsEnabled" Value="False" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=MyIsEnabled}" Value="False" >
                        <Setter Property="IsEnabled" Value="False" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </StackPanel.Resources>
        <StackPanel Orientation="Horizontal">
            <Label>MyIsEnabled</Label>
            <CheckBox IsChecked="{Binding Path=MyIsEnabled}" />
        </StackPanel>
        <TextBox Name="InputText">A block of text.</TextBox>
        <Button Name="TheButton" Content="A big button.">     
        </Button>
    </StackPanel>

I set DataContext to the Window class which has a DependencyProperty called MyIsEnabled. Obviously you would have to modify for your particular DataContext.

Here is the relevant code-behind:

public bool MyIsEnabled
{
    get { return (bool)GetValue(IsEnabledProperty); }
    set { SetValue(IsEnabledProperty, value); }
}

public static readonly DependencyProperty MyIsEnabledProperty =
    DependencyProperty.Register("MyIsEnabled", typeof(bool), typeof(MainWindow), new UIPropertyMetadata(true));


public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
}

Hope that helps!

Aegis answered 6/9, 2012 at 20:24 Comment(0)
S
7

As GazTheDestroyer said you can use MultiBinding.

You can also acomplish this with XAML-only solution using MultiDataTrigger

But you should switch the conditions cause triggers support only equality

<Style.Triggers>  
  <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
          <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text.Length}" Value="0" />
          <Condition Binding="{Binding Source=... Path=IsEnabled}" Value="False" />
        </MultiDataTrigger.Conditions>
        <Setter Property="IsEnabled" Value="False" />
      </MultiDataTrigger>  
</Style.Triggers>

If one of the condition is not met the value be set to its default or value from the style. But do not set local value as it overrides style's and trigger's values.

Spleenful answered 6/9, 2012 at 20:2 Comment(2)
That would result in an AND of those values. You could simply have two Triggers to each of those properties. Also, you would need to bind to a TextBox's Text.Length, not Self.Aegis
Yes, this is the AND, but Keith needs OR for not switched variants. Either user.IsEnabled OR Text.Length > 0 for enabling TextBox. See the comments ander the question.Spleenful
A
6

Since you only need a logical OR, you just need two Triggers to your each of the properties.

Try this XAML:

<StackPanel>
        <StackPanel.Resources>
            <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=InputText, Path=Text}" Value="" >
                        <Setter Property="IsEnabled" Value="False" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=MyIsEnabled}" Value="False" >
                        <Setter Property="IsEnabled" Value="False" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </StackPanel.Resources>
        <StackPanel Orientation="Horizontal">
            <Label>MyIsEnabled</Label>
            <CheckBox IsChecked="{Binding Path=MyIsEnabled}" />
        </StackPanel>
        <TextBox Name="InputText">A block of text.</TextBox>
        <Button Name="TheButton" Content="A big button.">     
        </Button>
    </StackPanel>

I set DataContext to the Window class which has a DependencyProperty called MyIsEnabled. Obviously you would have to modify for your particular DataContext.

Here is the relevant code-behind:

public bool MyIsEnabled
{
    get { return (bool)GetValue(IsEnabledProperty); }
    set { SetValue(IsEnabledProperty, value); }
}

public static readonly DependencyProperty MyIsEnabledProperty =
    DependencyProperty.Register("MyIsEnabled", typeof(bool), typeof(MainWindow), new UIPropertyMetadata(true));


public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
}

Hope that helps!

Aegis answered 6/9, 2012 at 20:24 Comment(0)
D
1

Bind IsEnabled using a MultiBinding

Dealings answered 6/9, 2012 at 19:39 Comment(4)
I tried that but Multibinding is not available to IsEnable, Unless I did something wrongLiebman
IsEnabled, not IsEnable? Don't you just mistype in your bindings? Add some XAML to your question.Spleenful
This is how I am currently doing it. But I did not want to have to wrap every control with a ContentControl. I tried setting up the style examples show above, but that messes up my Theme I am using. Since I am still learning WPF, I was wondering what options were available.Liebman
<ContentControl IsEnabled="{Binding Path=Enabled, Source={StaticResource UserInfo}}"> <TextBox DataContext="{DynamicResource UserInfo}" Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding Path=Text, RelativeSource={RelativeSource Self}, Converter={StaticResource LengthToBool}}"/> </ContentControl> Liebman

© 2022 - 2024 — McMap. All rights reserved.