0

CollectionView にバインドして、DataGrid にデータを表示しています。バインドは正常に機能しますが、読み取り専用のようです。グリッドのチェックボックスをオンにしてもモデルは更新されません。

削減の不条理:

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

2 に答える 2

0

クラスに INotifyPropertyChanged を実装し、次のように IsChecked プロパティを定義しようとしましたか:

 public virtual bool IsChecked
    {
        get
        { return _isChecked; }
        set
        {
            if (_isChecked != value)
            {
                _isChecked = value;
                OnPropertyChanged("IsChecked");
            }
        }
    }
于 2016-08-27T10:33:18.443 に答える
0

はい、わかった。

ばかげた理由で、コレクションにバインドするときの既定のバインド モードは OneWay であり、UpdateSourceTrigger は PropertyChanged ではありません。ドキュメントには、バインディングが一方向であると記載されていますが、更新トリガーも異なるとは言及されていません...

したがって、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 を使用することも最も効率的です。

最後に、リストよりも ObservableCollection を選択することをお勧めします。アイテムの挿入/削除は無料で同期されます。

于 2016-08-27T18:40:35.980 に答える