2010-05-28 106 views
14

我正在使用wpf 4.0中的datagrid。这有一个包含复选框的TemplateColumn。复选框的IsChecked属性通过绑定进行设置。wpf 4.0 datagrid模板列双向绑定问题

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

我不得不提到,相同的代码在.net 3.5中与wpf工具包中的datagrid完美协作。

请看看.xaml和.cs内容。

由于提前,

罗兰

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

回答

34

你在你的复选框设定器isChecked = UpdateSourceTrigger中的PropertyChanged的DataTemplate中绑定: <CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

+0

这工作良好,但这不按预期工作。当你输入一个字母时,它立即改变对象。如果你有一个触发验证处理程序的触发器会发生什么。这意味着如果您输入1000个符号,它会激发1000次?这个不对。 – Dilshod 2013-03-25 13:54:26

+1

这可能是一个可接受的解决方案,用于跟踪LostFocus事件。 Vincent 2013-05-07 19:43:23

+0

@Dilshod如果一个类型为1000个符号,它是什么意思?我们正在谈论一个复选框,对吧? – 2013-05-09 13:43:05

5

这里的交易,数据网格的工作方式,是它创建了一个数据视图并显示它而不是原始数据,因此,当您简单地绑定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" 
/> 
... 
+3

我不认为这是真的。对于没有使用Sese的答案的CellEditingTemplate,它完美地适用于我。 CellEditingTemplate看起来像会使事情过度复杂化并使其对用户更加困难。点击复选框肯定需要多次点击。 – MikeKulls 2012-09-20 23:32:04