开发者

wpf 4.0 datagrid template column two-way binding problem

开发者 https://www.devze.com 2023-01-01 23:47 出处:网络
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.

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 UIP开发者_JS百科ropertyMetadata(false, OnIsSelectedChanged));

    private static void OnIsSelectedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        // this part is not reached
    }
}


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


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"
/>
...
0

精彩评论

暂无评论...
验证码 换一张
取 消