Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wpf 4.0 datagrid template column two-way binding problem

I'm using the datagrid from wpf 4.0. This has a TemplateColumn containing a checkbox. The IsChecked property of the checkbox is set via binding.

The problem is that even if I specify the binding mode explicitly to be TwoWay, it works only in one direction.

I have to mention that the same code works perfectly in .net 3.5 with the datagrid from the wpf toolkit.

Please take a look at the .xaml and .cs contents.

Thanks in advance,

Roland

<Window.Resources>
    <DataTemplate
        x:Key="IsSelectedColumnTemplate">
        <CheckBox
            IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"
            />
    </DataTemplate>
</Window.Resources>
<Grid>
    <DataGrid
        x:Name="dataGrid"
        AutoGenerateColumns="false"
        CanUserAddRows="False"
        CanUserDeleteRows="False"
        HeadersVisibility="Column"
        ItemsSource="{Binding}"
        >
        <DataGrid.Columns>
            <DataGridTemplateColumn 
                Header="Preselected"
                x:Name="myIsSelectedColumn" 
                CellTemplate="{StaticResource IsSelectedColumnTemplate}"
                CanUserSort="True"
                SortMemberPath="Orientation"
                Width="Auto"
                />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

and the related .cs content:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        ObservableCollection<DataObject> DataSource = new ObservableCollection<DataObject>();
        DataSource.Add(new DataObject());    
        DataSource.Add(new DataObject());          
        dataGrid.ItemsSource = DataSource;
    }
}

public class DataObject : DependencyObject
{
    public bool IsSelected
    {
        get { return (bool)GetValue(IsSelectedProperty); }
        set { SetValue(IsSelectedProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsSelected.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsSelectedProperty =
        DependencyProperty.Register("IsSelected", typeof(bool), typeof(DataObject), new UIPropertyMetadata(false, OnIsSelectedChanged));

    private static void OnIsSelectedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        // this part is not reached
    }
}
like image 621
rouwlee Avatar asked May 28 '10 14:05

rouwlee


2 Answers

You set UpdateSourceTrigger=PropertyChanged in your Checkbox IsChecked binding in the datatemplate: <CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

like image 181
Stefan Szasz Avatar answered Nov 11 '22 09:11

Stefan Szasz


Here's the deal, the way the data grid works, is that it creates a data view and displays it instead of the original data, therefore when you simply bind a property in the CellTemplate it doesn't get propagated from the view to the data.

What you need to do is use the CellEditingTemplate so that the data grid knows when you're editing, and can propagate it to the data when done (or it can undo it if you cancel).

Here's the modified XAML for you:

<Window.Resources>
    <DataTemplate x:Key="IsSelectedColumnTemplate">
        <TextBlock Text="{Binding IsSelected}"/>
    </DataTemplate>
    <DataTemplate x:Key="IsSelectedColumnTemplateEditing">
        <CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"/>
    </DataTemplate>
</Window.Resources>

...
<DataGridTemplateColumn 
    Header="Preselected"
    x:Name="myIsSelectedColumn" 
    CellTemplate="{StaticResource IsSelectedColumnTemplate}"
    CellEditingTemplate="{StaticResource IsSelectedColumnTemplateEditing}"
    CanUserSort="True"
    Width="Auto"
/>
...
like image 44
Aviad P. Avatar answered Nov 11 '22 10:11

Aviad P.