wpf 4.0 datagrid模板列双向绑定问题

发布于 2024-09-03 11:53:08 字数 2258 浏览 4 评论 0原文

我正在使用 wpf 4.0 中的数据网格。它有一个包含复选框的 TemplateColumn。复选框的 IsChecked 属性是通过绑定设置的。

问题是,即使我明确指定绑定模式为 TwoWay,它也只能在一个方向上工作。

我不得不提的是,相同的代码在 .net 3.5 中与 wpf 工具包中的数据网格完美配合。

请查看 .xaml 和 .cs 内容。

预先感谢

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>

和相关的 .cs 内容:

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
    }
}

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
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

↙温凉少女 2024-09-10 11:53:08

您在数据模板中的 Checkbox IsChecked 绑定中设置 UpdateSourceTrigger=PropertyChanged:
<代码><复选框
IsChecked="{绑定路径=IsSelected,模式=TwoWay,UpdateSourceTrigger=PropertyChanged}"
>>

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

幸福还没到 2024-09-10 11:53:08

事情是这样的,数据网格的工作方式是,它创建一个数据视图并显示它而不是原始数据,因此,当您简单地在 CellTemplate 中绑定属性时,它不会被传播从视图到数据。

您需要做的是使用 CellEditingTemplate 以便数据网格知道您何时进行编辑,并在完成后将其传播到数据(或者如果您取消则可以撤消编辑)。

这是为您修改的 XAML:

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

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"
/>
...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文