Search code examples
c#wpfbindingdatagrid

DataGrid: replacing a DataGridTextColumn with DataGridTemplateColumn - how to make Binding work


I have a WPF Datagrid with a few DataGridTextColumns and I want to repace one with my own custom control. However I can't figure out how to bind.

<DataGrid ItemsSource="{Binding Path=Entries, Mode=OneWay}" IsSynchronizedWithCurrentItem="True">      
    <DataGrid.Columns>
        <DataGridTextColumn Header="Comment" Binding="{Binding Path=Comment}" Width="Auto" />
    </DataGrid.Columns>
</DataGrid>

I have replaced it with:

<DataGrid ItemsSource="{Binding Path=Entries, Mode=OneWay}" IsSynchronizedWithCurrentItem="True">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Comment" Width="Auto">
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <StackPanel>
                        <x:customTextBox Text="{Binding Path=Comment}" />
                    </StackPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Path=Comment}" />
                    </StackPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

I also tried to set a RelativeSource without any success. Do you have any suggestions how to solve this?


Solution

  • This works for me using a textbox instead of whatever your control is.

    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <Grid>
        <DataGrid ItemsSource="{Binding Path=Entries, Mode=OneWay}" IsSynchronizedWithCurrentItem="True"
                  AutoGenerateColumns="False"
                  >
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Comment" Width="Auto">
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <TextBox Text="{Binding Path=Comment}" />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <TextBlock Text="{Binding Path=Comment}" />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
    </Window>
    enter code here
    

    MyItem is a viewmodel I happened to have in a scratch app.

    public partial class MainWindowViewModel : ObservableObject
    {
    
        [ObservableProperty]
        private ObservableCollection<MyItem> entries = new ObservableCollection<MyItem>
        (
            new List<MyItem>
            {
                 new MyItem{ IsChosen = false},
                 new MyItem{ IsChosen = true },
                 new MyItem{ IsChosen = true }
            }
        );
    }
    

    Looks like

    public partial class MyItem : ObservableObject
    {
        [ObservableProperty]
        private bool? isChosen;
    
        [ObservableProperty]
        private string comment = "Some test string";
    }
    

    enter image description here