C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

CheckBox によって GridRow を非表示にする /りんく (18/11/02(Fri) 11:19) #89152
Re[1]: CheckBox によって GridRow を非表示にする /Hongliang (18/11/02(Fri) 12:52) #89155
  └ Re[2]: CheckBox によって GridRow を非表示にする /りんく (18/11/02(Fri) 15:17) #89159 解決済み


親記事 / ▼[ 89155 ]
■89152 / 親階層)  CheckBox によって GridRow を非表示にする
□投稿者/ りんく (10回)-(2018/11/02(Fri) 11:19:27)

分類:[.NET 全般] 

Visual Studio 2017
C#
WPF

画面上には CheckBox が二つと DataGrid を一つ配置しています。
CheckBox はそれぞれ「男性」「女性」としています。
「男性」CheckBox を ON したときは DataGrid に「M」行のみを表示
「女性」CheckBox を ON したときは DataGrid に「F」行のみを表示
としたいのですが DataGrid の行を非表示にする方法がわかりません。
Xaml の Style だけで実現できるでしょうか?
DataGrid の ItemsSource に設定しているリストから
削除する方法以外に実現できる方法はありますか?
※ItemsSource に設定しているリストは ReactiveCollection です。

「男性」CheckBox ON
「女性」CheckBox ON
名前|性別
一郎|M
一子|F
次郎|M
二子|F
三郎|M
三子|F

「男性」CheckBox ON
「女性」CheckBox OFF
名前|性別
一郎|M
次郎|M
三郎|M

「男性」CheckBox OFF
「女性」CheckBox ON
名前|性別
一子|F
二子|F
三子|F
[ □ Tree ] 返信 編集キー/

▲[ 89152 ] / ▼[ 89159 ]
■89155 / 1階層)  Re[1]: CheckBox によって GridRow を非表示にする
□投稿者/ Hongliang (718回)-(2018/11/02(Fri) 12:52:09)
RowStyleでMultiDataTriggerを使ってVisibility.Collapsedにすることはできますが、DataGrid内のカーソルの動きが気持ち悪くなります。
(非表示の行も選択対象になっているので、上下キーで移動できなかったりとか)

CollectionViewSourceを使ってコードビハインドでフィルタするのがいいでしょう。
[ 親 89152 / □ Tree ] 返信 編集キー/

▲[ 89155 ] / 返信無し
■89159 / 2階層)  Re[2]: CheckBox によって GridRow を非表示にする
□投稿者/ りんく (11回)-(2018/11/02(Fri) 15:17:10)
2018/11/02(Fri) 15:17:44 編集(投稿者)
No89155 (Hongliang さん) に返信
> CollectionViewSourceを使ってコードビハインドでフィルタするのがいいでしょう。

ありがとうございます。
CollectionViewSource については初めてだったので調べてみました。
http://increment.hatenablog.com/entry/2015/10/19/205222
を参考に、Behavior にして確認してみました。
問題なくフィルタをかけることができました。
ありがとうございました。

確認した Behavior 大まかに記載しておきます。

class StaffInfoBehavior : Behavior<UserControl>
{
    private CollectionViewSource _collectionViewSource;
    private UserControl _control;

    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.Loaded += OnLoaded;
        this.AssociatedObject.Unloaded += OnUnloaded;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        this.AssociatedObject.Loaded -= OnLoaded;
        this.AssociatedObject.Unloaded -= OnUnloaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        _control = sender as UserControl;
        if (_control != null)
        {
            var vm = _control.DataContext as ViewModels.MainViewModel;
            if (vm != null)
            {
                // CollectionViewSource を設定する
                _collectionViewSource = new CollectionViewSource();
                _collectionViewSource.Filter += Staff_Filter;
                _collectionViewSource.Source = vm.StaffInfos;
                
                var datagrid = _control.FindName("staffList") as DataGrid;
                datagrid.ItemsSource = _collectionViewSource.View;

                // CheckBox にイベントを追加する
                var 男性Check = _control.FindName("男性Check") as CheckBox;
                男性Check.Checked += OnCheckedChanged;
                男性Check.Unchecked += OnCheckedChanged;

                var 女性Check = _control.FindName("女性Check") as CheckBox;
                女性Check.Checked += OnCheckedChanged;
                女性Check.Unchecked += OnCheckedChanged;
            }
        }
    }

    private void OnUnloaded(object sender, RoutedEventArgs e)
    {
        // CheckBox のイベントを削除する
        var 男性Check = _control.FindName("男性Check") as CheckBox;
        男性Check.Checked -= OnCheckedChanged;
        男性Check.Unchecked -= OnCheckedChanged;

        var 女性Check = _control.FindName("女性Check") as CheckBox;
        女性Check.Checked -= OnCheckedChanged;
        女性Check.Unchecked -= OnCheckedChanged;
    }

    // 表示をフィルタする
    private void Staff_Filter(object sender, FilterEventArgs e)
    {
        if (e.Item != null)
        {
            var item = e.Item as StaffInfo;
            if(item != null)
            {
                if (item.Gender == "M")
                {
                    var check = _control?.FindName("男性Check") as CheckBox;
                    e.Accepted = check.IsChecked.Value;
                }
                else if (item.Gender == "F")
                {
                    var check = _control?.FindName("女性Check") as CheckBox;
                    e.Accepted = check.IsChecked.Value;
                }
            }
        }
    }

    // フィルタを更新する
    private void OnCheckedChanged(object sender, RoutedEventArgs e)
    {
        _collectionViewSource?.View.Refresh();
    }
}

解決済み
[ 親 89152 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -