Question

I am trying to apply some conditional formatting on a WPF DataGrid.The requirement is as follows. For any cell on the grid, if the content is an integer, the display format should be zero decimal places. If the contents have decimal places, then display them to the default value defined in the stringformat.

Does anybody have any idea as to how I could achieve this kind of conditional formatting? I have written a converter which can check for the existence of decimals but I have been unable to work out how I would be able to apply this in my XAML to either my cell style or my text column.

Cell Style - This is the style that I would like to define

<Style x:Key="MyCellStyle" TargetType="DataGridCell">
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>

Grid Column - I would to apply the style applied to this column

<DataGridTextColumn x:Key="ColumnName"
                    Header="ColumnName"
                    SortMemberPath="MyColumnSort"
                    Binding="{Binding myColBinding, StringFormat={}{0:N2}}"
                    IsReadOnly="True"
                    Width="40" />

Converter - I would use this converter to determine whether this style gets applied.

public class NoDecimalConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int converted;
            int.TryParse(value.ToString(), out converted);
            value.ToString();
            return int.TryParse(value.ToString(), out converted);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

I tried to do it by adding a datatrigger to my cell style as below but I got an error stating "Cannot find the Style Property 'StringFormat' on the type 'System.Windows.Controls.DataGridCell'."

    <Style x:Key="MyCellStyle" TargetType="DataGridCell">
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Style.Triggers>             
            <DataTrigger Binding="{Binding NoDecimalConvertor}" Value="False" >                 
                <Setter Property="StringFormat" Value="true" />             
            </DataTrigger>         
        </Style.Triggers>     
</Style>

I have been banging my head against this for days so any guidance would be appreciated as to the best way to approach this.

Was it helpful?

Solution

Your converter is currently returning a boolean to indicate whether or not it could parse an integer from the string value. Instead, you should try something like this:

public class NoDecimalConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int converted;
        if (int.TryParse(value.ToString(), out converted))
             return converted.ToString();

        double convertedDouble;
        if (double.TryParse(value.ToString(), out convertedDouble))
             return convertedDouble.ToString();

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

This will first try to parse an int, and return it (as a string) if successful. If not, it will try a double and return it - here you could specify any string format to get the desired number of decimal places etc. Finally, if it can't parse either it will return the original value.

You can then set that on your column using:

<DataGridTextColumn x:Key="ColumnName"
                Header="ColumnName"
                SortMemberPath="MyColumnSort"
                Binding="{Binding myColBinding, Converter={StaticResource MyConverter}}"
                IsReadOnly="True"
                Width="40" />

Note: you will need to instantiate your converter somewhere in the resources with a key of MyConverter.

If you want to be able to specify a default number of decimal places, you could pass it in as a converter parameter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top