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

わんくま同盟

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

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

ツリー一括表示

WPFのDataGridでフィルタリングしたい /くろ (19/05/13(Mon) 22:55) #90920
Re[1]: WPFのDataGridでフィルタリングしたい /Hongliang (19/05/14(Tue) 06:31) #90921
  └ Re[2]: WPFのDataGridでフィルタリングしたい /くろ (19/05/14(Tue) 11:50) #90928
    └ Re[3]: WPFのDataGridでフィルタリングしたい /Hongliang (19/05/14(Tue) 13:54) #90935
      └ Re[4]: WPFのDataGridでフィルタリングしたい /くろ (19/05/14(Tue) 14:12) #90938 解決済み


親記事 / ▼[ 90921 ]
■90920 / 親階層)  WPFのDataGridでフィルタリングしたい
□投稿者/ くろ (23回)-(2019/05/13(Mon) 22:55:47)

分類:[C#] 

WPFのDataGridのヘッダにテキストボックスを配置し
TextChangedイベントでフィルタリングしています。
通常の入力時は正常にフィルタリングされるのですが
コピーペーストすると「CollectionViewSource.View.Refresh();」で以下のエラーが発生します。
System.InvalidOperationException: ''Refresh' は、AddNew トランザクションまたは EditItem トランザクションの実行中は許可されません。'

どのような回避方法があるでしょうか。

private CollectionViewSource CollectionViewSource { get; set; }
textBox.TextChanged += (object sender, TextChangedEventArgs e) =>
{
  CollectionViewSource.View.Refresh();
};
CollectionViewSource.Filter += (object sender, FilterEventArgs e) =>
{
  if (e.Item != null)
  {
    // フィルタリング
  }
};

[ □ Tree ] 返信 編集キー/

▲[ 90920 ] / ▼[ 90928 ]
■90921 / 1階層)  Re[1]: WPFのDataGridでフィルタリングしたい
□投稿者/ Hongliang (797回)-(2019/05/14(Tue) 06:31:48)
手元では再現しなかったので何が悪いというのは言えませんが、
Refresh()を
CollectionViewSource.IsLiveFilteringRequested = false;
CollectionViewSource.IsLiveFilteringRequested = true;
の2行に変更してみてはどうでしょうか。
[ 親 90920 / □ Tree ] 返信 編集キー/

▲[ 90921 ] / ▼[ 90935 ]
■90928 / 2階層)  Re[2]: WPFのDataGridでフィルタリングしたい
□投稿者/ くろ (24回)-(2019/05/14(Tue) 11:50:00)
ありがとうございます。
ソースをシンプルにしましたが発生しました。

グリッドのセルをダブルクリックしてセル文字列をコピーして
フィルタリングのテキストボックスに値を貼り付けると発生するようです。
テキストファイルからなど他からコピーすれば発生しませんでした。

XAML
<Window x:Class="MainWindow"
        x:Name="_this"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Grid>
        <DataGrid x:Name="dataGrid" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" >
        </DataGrid>     
    </Grid>    
</Window>


C#のコード
        public MainWindow()
        {
            InitializeComponent();

            InitDataTable();
        }

        private void InitDataTable()
        {
            dataGrid.AutoGenerateColumns = false;
            CollectionViewSource collectionViewSource = new CollectionViewSource();

            for (int n = 0; n < 5; n++)
            {
                // パネルの生成
                StackPanel panel = new StackPanel();
                TextBox textBox = new TextBox();
                panel.Children.Add(new TextBlock() { Text = "カラム" + n });
                panel.Children.Add(textBox);

                // 変更時フィルタイベントの実行
                textBox.TextChanged += (object sender, TextChangedEventArgs e) =>
                {
                    collectionViewSource.IsLiveFilteringRequested = false;
                    collectionViewSource.IsLiveFilteringRequested = true;
                };

                // カラム追加
                var dgtc = new DataGridTextColumn()
                {
                    Header = panel,
                    Binding = new Binding("[カラム" + n + "]"),
                    IsReadOnly = false,
                    MaxWidth = 100,
                };

                dataGrid.Columns.Add(dgtc);
            }


            // データの生成
            List<Hashtable> list = new List<Hashtable>();
            for (int i = 0; i < 10; i++)
            {
                Hashtable t = new Hashtable();
                list.Add(t);
                for (int n = 0; n < 5; n++)
                {
                    t["カラム" + n] = "値_" + n + "_" + i;
                }
            }

            collectionViewSource.Source = list;
            dataGrid.ItemsSource = collectionViewSource.View;
        }

[ 親 90920 / □ Tree ] 返信 編集キー/

▲[ 90928 ] / ▼[ 90938 ]
■90935 / 3階層)  Re[3]: WPFのDataGridでフィルタリングしたい
□投稿者/ Hongliang (798回)-(2019/05/14(Tue) 13:54:13)
なるほど、状況を把握しました。

DataGridにはセル編集中および行編集中という状態があります。
またList<T>クラスなどをもとにして作られたCollectionViewは実体がListCollectionViewですが、これには編集中という状態があります。
ListCollectionViewの編集中はDataGridの行編集中に対応しています。

DataGridの行編集は、カレント行を変更する、DataGrid外にフォーカスを移す、等で確定されるようですが、DataGridの列ヘッダだとその条件を満たさず、行編集中状態が維持されます。
ListCollectionViewは編集中に更新はできないようになっていて(例えば入力中にソートによって入力位置がすっ飛んだりするのを防ぐためとか、理由はいくつか思いつきます)、その条件に引っ掛かったというわけですね。

行の編集を受け入れて問題ないのであれば、DataGridのCommitEdit(DataGridEditingUnit.Row, true)を呼び出せば行編集が完了=ListCollectionViewの編集状態が解除されて、フィルタの再適用が可能になります。
[ 親 90920 / □ Tree ] 返信 編集キー/

▲[ 90935 ] / 返信無し
■90938 / 4階層)  Re[4]: WPFのDataGridでフィルタリングしたい
□投稿者/ くろ (25回)-(2019/05/14(Tue) 14:12:40)
丁寧なご説明ありがとうございます。

Refresh直前にCommitEditする事で解決いたしました。

度々のご回答ありがとうございました。

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


管理者用

- Child Tree -