Search code examples
c#wpfbindingdatagridivalueconverter

WPF IValueConverter with Radio Buttons


I have a datagrid to which a list of objects is binded. Each object has a Number property. I have 2 radio buttons,if the first is checked then the default value should appear in the column,but if the second radio button is checked, I want to divide the whole column by 1000. I tried using IValueConverter, but when i add the Converter to the Binding of the DataGridTextColumn, the Number column is empty. I DON'T want to change the property in the object, only in the UI. How could I achieve this to work?

The code I tried:

 public class NumberConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is long numValue)
            return numValue / 1000.0;
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is long numValue)
            return numValue * 1000.0;
        return value;
    }
}

The XAML code:

<Window.Resources>
  <local:NumberConverter x:Key="NumberConverter"/>
</Window.Resources>

               <RadioButton 
                    Grid.Column="1"
                    HorizontalAlignment="Right"
                    x:Name="MultiplyBy1000" 
                    GroupName="chkFormat" 
                    Content="Default" 
                    IsChecked="{Binding IsDefaultChecked}"
                    Margin="5"/>

                <RadioButton 
                    Grid.Column="2"
                    HorizontalAlignment="Left"
                    x:Name="DivideBy1000"
                    GroupName="chkFormat" 
                    Content="Divide by 1000"
                    IsChecked="{Binding IsDivideNumChecked}"
                    Margin="5"/>

....

<DataGridTextColumn Header="Number" Width="0.7*" Binding="{Binding Number,Converter={StaticResource NumberConverter}"/>

Solution

  • You need to use MultiValueConverter and bind the value and the radio button's IsChecked value.

    A value converter like the below:

    
    public class ConditionalDividerConverter: IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var divide = (bool)values[0];
            var value = (double)values[1];
            return divide ? value / 1000 : value;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException("Not implemented");
        }
    }
    

    And the usage of the binding :

    <DataGridTextColumn Header="Number" Width="0.7*" >
      <DataGridTextColumn.Binding>
        <MutliBinding Converter="{StaticResource conditionalDividerConverter}">
          <MultiBinding.Bindings>
            <Binding ElementName="DivideBy1000" Path="IsChecked" />
            <Binding Path="Number" />
          </MultiBinding.Bindings>
        </MultiBinding>
      </DataGridTextColumn.Binding>
    </DataGridTextColumn>