WPF DataGrid change cell value based on underlying data object

XAML

<Window x:Class="DataGridCellBackground.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:DataGridCellBackground="clr-namespace:DataGridCellBackground"
    Title="MainWindow" Height="350" Width="525"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
  <Window.Resources>    
    <DataGridCellBackground:DataGridCellValueConverter x:Key="dataGridCellValueConverter"/>
  </Window.Resources>
  <Grid>    
    <DataGrid ItemsSource="{Binding Data}" Width="400" Height="200" CanUserAddRows="False">
      <DataGrid.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="DataGridCell">                
                <TextBlock>
                  <ContentPresenter>
                    <ContentPresenter.Content>
                      <MultiBinding Converter="{StaticResource dataGridCellValueConverter}" >
                        <MultiBinding.Bindings>
                          <Binding RelativeSource="{RelativeSource AncestorType={x:Type DataGridCell}}"></Binding>
                          <Binding Path="Row"></Binding>
                        </MultiBinding.Bindings>
                      </MultiBinding>
                    </ContentPresenter.Content>
                  </ContentPresenter>
                </TextBlock>                
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </DataGrid.CellStyle>
    </DataGrid>    
  </Grid>
</Window>

Code Behind

namespace DataGridCellBackground
{  
  public partial class MainWindow : Window
  {
    public MainWindow()
    {           
      InitializeComponent();            
    }
 
    public DataTable Data { 
      get{
        var data = new DataTable();
  
        data.Columns.Add("Text", typeof(string));
        data.Columns.Add("Value", typeof(ComplexValue));
  
        var row = data.NewRow();
        row["Text"] = "First";
        row["Value"] = new ComplexValue() { Value = 1, Checked = true };
        data.Rows.Add(row);
 
        row = data.NewRow();
        row["Text"] = "Second";
        row["Value"] = new ComplexValue() { Value = 2, Checked = false };
        data.Rows.Add(row);
 
        row = data.NewRow();
        row["Text"] = "Third";
        row["Value"] = new ComplexValue() { Value = 3, Checked = true };
        data.Rows.Add(row);
     
        return data;
      }
    } 
 
  public class ComplexValue
  {
    public int Value { get; set; }
    public bool Checked { get; set; }
  }
}
 
  public class DataGridCellValueConverter : IMultiValueConverter
  {
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
      if (values.Length>0 && values[1] is DataRow)
      {
        var cell = (DataGridCell)values[0];
        var row = (DataRow)values[1];
        var columnName = cell.Column.SortMemberPath;
        var value = row[columnName];
        if (value is MainWindow.ComplexValue)
        {
          return (value as MainWindow.ComplexValue).Value;
        }else
        {
          return value;
        }               
      }
      return null;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
      throw new System.NotImplementedException();
    }
  }
}

Comments

Popular posts from this blog

Parse XML to dynamic object in C#

C# Updating GUI from different thread