WPF ICollectionView 双向绑定?
WPF ICollectionView Two Way Binding?
我在 DataGrid 中显示一些数据,绑定到 CollectionView。绑定工作正常,但似乎是只读的:选中网格中的复选框不会更新模型。
减少广告荒谬:
public class Item
{
public bool IsChecked
{
get
{
return _isChecked;
}
set
{
// Not hit when clicking on checkbox
_isChecked = value;
}
}
private bool _isChecked;
}
代码隐藏,我的集合视图是一个依赖项属性:
private static DependencyProperty __CollectionViewProperty = DependencyProperty.Register
(
"_CollectionView",
typeof( ICollectionView ),
typeof( MyClass ),
new PropertyMetadata( null )
);
private ICollectionView _CollectionView
{
get { return ( ICollectionView )GetValue( __CollectionViewProperty ); }
set { SetValue( __CollectionViewProperty, value ); }
}
并像这样实例化:
List<Item> items = new List<Item>();
items.Add( new Item() );
this._CollectionView = CollectionViewSource.GetDefaultView( items );
在 xaml 中,我只是将 DataGrid 绑定到 _CollectionView,并将复选框绑定到 IsChecked。没有异常,并且 IsChecked 的状态正确反映在 UI 中。
但是单击复选框只会更新 UI,不会更新模型。我是 WPF 的新手,来自 Cocoa,其中等效项是 NSArrayController,并且绑定可以直接使用两种方式。我错过了什么?
编辑:xml 代码:
<DataGrid Grid.Row="1" ItemsSource="{ Binding _CollectionView}" AutoGenerateColumns="False" GridLinesVisibility="None"
RowHeight="60" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollBarVisibility="Hidden"
CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserSortColumns="True" IsSynchronizedWithCurrentItem="True"
x:Name="_DataGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="" Width="90" CanUserSort="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Click="CheckBox_Click" HorizontalAlignment="Left"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGrid.Columns>
</DataGrid>
您是否尝试在 class 上实施 INotifyPropertyChanged 并像这样定义 IsChecked 属性 :
public virtual bool IsChecked
{
get
{ return _isChecked; }
set
{
if (_isChecked != value)
{
_isChecked = value;
OnPropertyChanged("IsChecked");
}
}
}
好的,明白了。
出于某些愚蠢的原因,绑定到集合时默认的绑定模式是单向模式,而 UpdateSourceTrigger 不是 PropertyChanged。 docs 提到绑定是一种方式,但更新触发器也不同...
因此,xaml 绑定变为:
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
要将对源的更改也正确传播到目标 UI 组件,最简单的方法是从 DependencyObject 继承,并将相关属性声明为依赖属性:
public class Item : DependencyObject
{
private static DependencyProperty __IsCheckedProperty = DependencyProperty.Register
(
"IsChecked",
typeof( bool ),
typeof( iOSAppItem ),
new PropertyMetadata( true )
);
public bool IsChecked
{
get { return ( bool )GetValue( __IsCheckedProperty ); }
set { SetValue( __IsCheckedProperty, value ); }
}
}
根据文档,使用 DependencyProperty 也是 the most efficient。
最后,选择 ObservableCollection 而不是 List 是个好主意:insertion/deletion 项将免费同步。
我在 DataGrid 中显示一些数据,绑定到 CollectionView。绑定工作正常,但似乎是只读的:选中网格中的复选框不会更新模型。
减少广告荒谬:
public class Item
{
public bool IsChecked
{
get
{
return _isChecked;
}
set
{
// Not hit when clicking on checkbox
_isChecked = value;
}
}
private bool _isChecked;
}
代码隐藏,我的集合视图是一个依赖项属性:
private static DependencyProperty __CollectionViewProperty = DependencyProperty.Register
(
"_CollectionView",
typeof( ICollectionView ),
typeof( MyClass ),
new PropertyMetadata( null )
);
private ICollectionView _CollectionView
{
get { return ( ICollectionView )GetValue( __CollectionViewProperty ); }
set { SetValue( __CollectionViewProperty, value ); }
}
并像这样实例化:
List<Item> items = new List<Item>();
items.Add( new Item() );
this._CollectionView = CollectionViewSource.GetDefaultView( items );
在 xaml 中,我只是将 DataGrid 绑定到 _CollectionView,并将复选框绑定到 IsChecked。没有异常,并且 IsChecked 的状态正确反映在 UI 中。
但是单击复选框只会更新 UI,不会更新模型。我是 WPF 的新手,来自 Cocoa,其中等效项是 NSArrayController,并且绑定可以直接使用两种方式。我错过了什么?
编辑:xml 代码:
<DataGrid Grid.Row="1" ItemsSource="{ Binding _CollectionView}" AutoGenerateColumns="False" GridLinesVisibility="None"
RowHeight="60" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollBarVisibility="Hidden"
CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserSortColumns="True" IsSynchronizedWithCurrentItem="True"
x:Name="_DataGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="" Width="90" CanUserSort="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Click="CheckBox_Click" HorizontalAlignment="Left"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGrid.Columns>
</DataGrid>
您是否尝试在 class 上实施 INotifyPropertyChanged 并像这样定义 IsChecked 属性 :
public virtual bool IsChecked
{
get
{ return _isChecked; }
set
{
if (_isChecked != value)
{
_isChecked = value;
OnPropertyChanged("IsChecked");
}
}
}
好的,明白了。
出于某些愚蠢的原因,绑定到集合时默认的绑定模式是单向模式,而 UpdateSourceTrigger 不是 PropertyChanged。 docs 提到绑定是一种方式,但更新触发器也不同...
因此,xaml 绑定变为:
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
要将对源的更改也正确传播到目标 UI 组件,最简单的方法是从 DependencyObject 继承,并将相关属性声明为依赖属性:
public class Item : DependencyObject
{
private static DependencyProperty __IsCheckedProperty = DependencyProperty.Register
(
"IsChecked",
typeof( bool ),
typeof( iOSAppItem ),
new PropertyMetadata( true )
);
public bool IsChecked
{
get { return ( bool )GetValue( __IsCheckedProperty ); }
set { SetValue( __IsCheckedProperty, value ); }
}
}
根据文档,使用 DependencyProperty 也是 the most efficient。
最后,选择 ObservableCollection 而不是 List 是个好主意:insertion/deletion 项将免费同步。