0

I'm trying to bind a TextBox text on a RadioButton check event:

[User interface with text box and radio buttons.1

What I want to do is: Ehen the "SAV" or "HORS CIRCUIT" or "AUCUNE" radiobutton are checked, then the "Adr Mac" textbox becomes empty, with this Xaml code:

<TextBox x:Name="AdrMac_TxtBox">
   <TextBox.Style>
      <Style TargetType="{x:Type TextBox}">
         <Setter Property="BorderBrush" Value="Black"/>
         <Setter Property="Width" Value="100"/>
         <Setter Property="HorizontalContentAlignment" Value="Left"/>
         <Setter Property="VerticalContentAlignment" Value="Center"/>
         <Setter Property="Padding" Value="5"/>
         <Setter Property="Margin" Value="5"/>
         <Setter Property="HorizontalAlignment" Value="Left"/>
         <Style.Triggers>
            <Trigger Property="IsEnabled" Value="False">
               <Setter Property="Background" Value="LightGray"/>
               <Setter Property="Opacity" Value="0.5"/>
            </Trigger>
            <MultiDataTrigger>
               <MultiDataTrigger.Conditions>
                  <Condition Binding="{Binding Path=IsChecked,ElementName=None_Imprim_Rb}"
                                                           Value="True"/>
                  <Condition Binding="{Binding Path=IsChecked,ElementName=Sav_Rb_Checked}"
                                                           Value="True"/>
                  <Condition Binding="{Binding Path=IsChecked,ElementName=HC_Rb_Checked}"
                                                           Value="True"/>
               </MultiDataTrigger.Conditions>
               <Setter Property="Text" Value="{x:Static sys:String.Empty}"/>
            </MultiDataTrigger>
         </Style.Triggers>
      </Style>
   </TextBox.Style>
</TextBox>

Can you tell me what is wrong with this code ?

thatguy
  • 21,059
  • 6
  • 30
  • 40
  • `MultiDataTrigger` executes the Setters if _all_ of the conditions are met. You may have success when you define separate Triggers for each of the conditions. – Klaus Gütter Oct 11 '20 at 05:27

2 Answers2

0

Here's a simple example of a TextBox with two triggers, when either radio is selected it'll clear the TextBox text, please note the multiple <DataTrigger>:

<TextBox Height="23" Width="120">
    <TextBox.Style>
        <Style TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsChecked, ElementName=rb_One}" Value="True">
                    <Setter Property="Text" Value="{x:Null}"></Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsChecked, ElementName=rb_Two}" Value="True">
                    <Setter Property="Text" Value="{x:Null}"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>
<RadioButton x:Name="rb_One" Content="RadioButton" />
<RadioButton x:Name="rb_Two" Content="RadioButton" />
kshkarin
  • 574
  • 4
  • 9
0

A MultiDataTrigger will only apply setters, when all conditions are met.

Represents a trigger that applies property values or performs actions when the bound data meet a set of conditions.

You could instead define multiple DataTriggers that each act on a single condition.

<Style.Triggers>
   <!-- ...other tiggers. -->
   <DataTrigger Binding="{Binding Path=IsChecked,ElementName=None_Imprim_Rb}" Value="True">
      <Setter Property="Text" Value="{x:Static sys:String.Empty}"/>
   </DataTrigger>
   <DataTrigger Binding="{Binding Path=IsChecked,ElementName=Sav_Rb_Checked}" Value="True">
      <Setter Property="Text" Value="{x:Static sys:String.Empty}"/>
   </DataTrigger>
   <DataTrigger Binding="{Binding Path=IsChecked,ElementName=HC_Rb_Checked}" Value="True">
      <Setter Property="Text" Value="{x:Static sys:String.Empty}"/>
   </DataTrigger>
</Style.Triggers>

In case you want to prevent redundant setters, you could create a boolean OR multi-value converter.

public class BooleanOrConverter : IMultiValueConverter
{
   public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
   {
      return values.Cast<bool>().Any(value => value);
   }

   public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
   {
      throw new InvalidOperationException();
   }
}

Then you can use a DataTrigger with a MultiBinding to achieve the same.

<TextBox x:Name="AdrMac_TxtBox">
   <TextBox.Resources>
      <local:BooleanOrConverter x:Key="BooleanOrConverter"/>
   </TextBox.Resources>
   <TextBox.Style>
      <Style TargetType="{x:Type TextBox}">
         <!-- ...your setters. -->
         <Style.Triggers>
            <!-- ...other triggers. -->
            <DataTrigger Value="True">
               <DataTrigger.Binding>
                  <MultiBinding Converter="{StaticResource BooleanOrConverter}">
                     <Binding ElementName="None_Imprim_Rb" Path="IsChecked"/>
                     <Binding ElementName="Sav_Rb_Checked" Path="IsChecked"/>
                     <Binding ElementName="HC_Rb_Checked" Path="IsChecked"/>
                  </MultiBinding>
               </DataTrigger.Binding>
               <Setter Property="Text" Value="{x:Static sys:String.Empty}"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBox.Style>
</TextBox>
thatguy
  • 21,059
  • 6
  • 30
  • 40
  • When i run the app the piece of code returns an invalid cast error : "return values.Cast().Any(value => value);" –  Oct 14 '20 at 16:34
  • @JeanFrançoisCollombet One of the values could be `DependencyProperty.UnsetValue`. That value is set when the property system cannot determine the bound value, e.g. the control you reference does not exist. See this [related question](https://stackoverflow.com/questions/2811405/why-do-i-get-a-dependencyproperty-unsetvalue-when-converting-a-value-in-a-multib). If you do not get around this issue, you can make the converter ignore them with this: `return values.All(value => value != DependencyProperty.UnsetValue) && values.Cast().Any(value => value);`. But be sure to check the issue. – thatguy Oct 15 '20 at 11:47