Search code examples
c#wpfdata-bindingdatagrid

Set DataGrid cell value from variables not in DataSource


I have a DataGrid set with templates which get filled with a List in the ViewModel. The source is a custom class and so far every column takes a value from this class. However, I am trying to add a new column that (as an example) takes a value and doubles it. How can I go about this? This code has to be in the ViewModel, not the C# behind the view.

<DataGridTemplateColumn Header="MyHeader" MaxWidth="250">
    <!--Header Template-->
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            <TextBlock Text="{TemplateBinding Content}"/>
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>
    <!--Cell Template-->
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding MyBinding}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

DataGrid Definition (so ItemSource):

<DataGrid ItemsSource="{Binding Calibrations, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" AutoGenerateColumns="False" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">

Solution

  • try custom implementation of IValueConverter to produce value based on viewmodel property (or IMultiValueConverter if many viewmodel properties are involved):

    public class MultiplyConverter: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            double d = (double)value;
            double mult = (double)parameter;
            return d*mult;         
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    create an instance of converter in the view (in Resources):

    <DataGrid.Resources>
        <local:MultiplyConverter x:Key="mult" />
    <DataGrid.Resources>
    

    and then use it in Binding:

    <DataGridTextColumn Header="x2" IsReadOnly="True"
     Binding="{Binding Path=MyBinding, Converter={StaticResource mult}, ConverterParameter = 2.0}"/>