Reputation: 2228
I have two text boxes and one button. If either of the boxes is empty or white space, the button should be disabled.
<TextBox Name="firstNameTxtBox" />
<TextBox Name="lastNameTxtBox" />
<Button Content="Save" Command="{Binding Save}" Style="{StaticResource saveButtonEnabler}" />
And the saveButtonEnabler
resource:
<UserControl.Resources>
<converters:IsButtonEnabledConverter x:Key="isButtonEnabledConverter" />
<Style x:Key="saveButtonEnabler" TargetType="Button">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=firstNameTxtBox, Path=Text.Length, Converter={StaticResource isButtonEnabledConverter}}" Value="???" />
<Condition Binding="{Binding ElementName=lastNameTxtBox, Path=Text.Length, Converter={StaticResource isButtonEnabledConverter}}" Value="???" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
Converter gets called appropriately, but I have not idea how to set the result to the Value
of the Condition
.
public class IsButtonEnabledConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value == 0 ? false : true;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Upvotes: 9
Views: 16342
Reputation: 5121
Actually you need to use 2 triggers to set IsEnabled to false. Your current implementation is AND and what you want is OR.
<TextBox x:Name="firstNameTxtBox"/>
<TextBox x:Name="lastNameTxtBox"/>
<Button Content="Save">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding Text.Length, ElementName=firstNameTxtBox, UpdateSourceTrigger=PropertyChanged}" Value="0">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding Text.Length, ElementName=lastNameTxtBox, UpdateSourceTrigger=PropertyChanged}" Value="0">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
If you however want to use the valueconverter approach all you need to do is use 'True' as the Value in your trigger bindings as such
<Condition Binding="{Binding ElementName=firstNameTxtBox, Path=Text.Length, Converter={StaticResource isButtonEnabledConverter}}" Value="True" />
<Condition Binding="{Binding ElementName=lastNameTxtBox, Path=Text.Length, Converter={StaticResource isButtonEnabledConverter}}" Value="True" />
Upvotes: 14
Reputation: 39976
You can use IsEnabled
property of the button if you have one TextBox
:
<Button Content="Save" Command="{Binding Save}"
IsEnabled="{Binding ElementName=firstNameTxtBox, Path=Text.Length, Mode=OneWay}" />
For both TextBoxes
try this (You don't need to use converter):
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=firstNameTxtBox, Path=Text.Length, Mode=OneWay}" Value="0"/>
<Condition Binding="{Binding ElementName=lastNameTxtBox, Path=Text.Length, Mode=OneWay}" Value="0"/>
</MultiDataTrigger.Conditions>
Your complete code would be:
<TextBox Name="firstNameTxtBox" />
<TextBox Name="lastNameTxtBox" />
<Button Content="Save" Command="{Binding Save}" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=firstNameTxtBox, Path=Text.Length, Mode=OneWay}" Value="0"/>
<Condition Binding="{Binding ElementName=lastNameTxtBox, Path=Text.Length, Mode=OneWay}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Upvotes: 11
Reputation: 37790
This will work without converter:
<TextBox x:Name="Foo1"/>
<TextBox x:Name="Foo2"/>
<Button Content="Push me">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Text.Length, ElementName=Foo1, UpdateSourceTrigger=PropertyChanged}" Value="0"/>
<Condition Binding="{Binding Text.Length, ElementName=Foo2, UpdateSourceTrigger=PropertyChanged}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Upvotes: 2
Reputation: 2875
Your converter is returning a boolean, so you definitely have to set your value to True.
But I would change my converter a little bit: Instead of:
return (int)value == 0 ? false:true;
I would do:
return ((int)value) !=0;
Upvotes: 0