【问题标题】:WPF ICollectionView Two Way Binding?WPF ICollectionView 两种方式绑定?
【发布时间】:2017-01-03 22:26:33
【问题描述】:

我在 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>

【问题讨论】:

    标签: wpf binding datagrid icollectionview


    【解决方案1】:

    好的,明白了。

    出于某种愚蠢的原因,绑定到集合时的默认绑定模式是 OneWay,而 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 是个好主意:项目的插入/删除将免费同步。

    【讨论】:

      【解决方案2】:

      您是否尝试在您的类上实现 INotifyPropertyChanged 并像这样定义您的 IsChecked 属性:

       public virtual bool IsChecked
          {
              get
              { return _isChecked; }
              set
              {
                  if (_isChecked != value)
                  {
                      _isChecked = value;
                      OnPropertyChanged("IsChecked");
                  }
              }
          }
      

      【讨论】:

      • 你能复制你的 xaml 吗?
      • 已添加。也在监控点击事件,顺利通过。
      • 您能否将您的代码更新为 IsChecked="{Binding IsChecked,Mode=TwoWay}" ?
      • 你能第一次用 IsChecked = true 初始化你的列表,看看它是否反映在屏幕上吗?我怀疑 ItemsSource 并想确保复选框已正确绑定。
      • 正如我在问题中所写,UI 正确反映了项目的状态。 IsChecked 已读取,只是未设置...
      猜你喜欢
      • 2021-03-01
      • 1970-01-01
      • 2016-10-24
      • 2015-08-09
      • 2011-03-06
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      • 2016-02-27
      相关资源
      最近更新 更多