XamDataGridにはビルトインのフィルター機能があり、簡単なプロパティ設定で、入力式のフィルタからエクセルライクなものまで様々なフィルタ機能を利用することができます。
ビルトインのフィルタでは以下左の図で ”(カスタム)” という項目を選択するとカスタムフィルター専用のダイアログ(以下右の図)が表示され、指定列に対してカスタムな絞り込み条件を追加していくことができます。
今回はこのビルトインのカスタムフィルタダイアログを独自に作成した範囲指定専用のフィルタダイアログに置き換えてみたいと思います。
まずはじめに、Window内にXamDataGridを配置し、フィルタ機能を有効 ( AllowRecordFiltering = True ) に設定します。(データバインド部分についての説明は割愛します。本記事に添付のサンプルをご参照下さい。)
<!--XamDatagridの設定--> <igDP:XamDataGrid Name="xgrid1" DataSource="{Binding People}"> <igDP:XamDataGrid.FieldSettings> <igDP:FieldSettings AllowRecordFiltering="True" FilterOperandUIType="Combo"/> </igDP:XamDataGrid.FieldSettings> <igDP:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings SelectionTypeRecord="Single"/> </igDP:XamDataGrid.FieldLayoutSettings> <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:FieldLayout.Fields> <igDP:Field Name="Name"> </igDP:Field> </igDP:FieldLayout.Fields> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid>
これだけでフィルタ機能が有効になります。
次に、フィルタのドロップダウンを展開した際に表示される ”(カスタム)” という文字を ”(範囲選択)” に変換します。各フィルタアイテムのテキスト値を IValueConverter を利用して変換する手もありますが、ここでは、フィルタのリスト部分が表示される際に発生する RecordFilterDropDownPopulating イベントを利用して変換します。
//フィルタメニューが出るタイミングのイベント void xgrid1_RecordFilterDropDownPopulating(object sender, Infragistics.Windows.DataPresenter.Events.RecordFilterDropDownPopulatingEventArgs e) { //(カスタム)を(範囲選択)に変更 e.DropDownItems[0].DisplayText = "(範囲選択)"; }
※ DropDownItems 指定をインデックス固定で行っていますが、ケースによってはループ文で検証したほうが良いです。このコレクションはこのイベントの中で追加や削除することができます。
現時点ではフィルタアイテムの ”(カスタム)” という表示が ”(範囲選択)” になっただけなので、 ”(範囲選択)” をクリックするとビルトインのカスタムフィルタダイアログが表示されます。そこで CustomFilterSelectionControlOpening イベントでこのビルトインのダイアログ表示をキャンセルし、自作したダイアログ(今回は XamDialogWindow を利用)を表示させたいと思います。
まずはXamDialogWindowの自作ダイアログの定義部分。ポイントは、IsModal プロパティを False に設定し、ダイアログ表示時にダイアログ外を操作させないことです。
<!--XamDialogWindowの設定--> <ig:XamDialogWindow Height="136" HorizontalAlignment="Left" Name="xamDialogWindow1" Width="315" CloseButtonVisibility="Hidden" MaximizeButtonVisibility="Hidden" MinimizeButtonVisibility="Hidden" IsModal="True"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="71*" /> <ColumnDefinition Width="228*" /> </Grid.ColumnDefinitions> <TextBlock Height="23" Margin="15,10,17,0" Name="textBlock1" Text="From" VerticalAlignment="Top" /> <TextBox Height="24" HorizontalAlignment="Right" Margin="0,9,12,0" Name="textBox1" VerticalAlignment="Top" Width="224" Grid.ColumnSpan="2" /> <Button Content="OK" Height="23" HorizontalAlignment="Left" Margin="142,65,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" Grid.Column="1" /> <TextBlock Height="23" Margin="15,39,14,0" Name="textBlock2" Text="To" VerticalAlignment="Top" /> <TextBox Height="24" HorizontalAlignment="Right" Margin="0,36,12,0" Name="textBox2" VerticalAlignment="Top" Width="224" Grid.ColumnSpan="2" /> <Button Content="Cancel" Height="23" HorizontalAlignment="Left" Margin="61,65,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" Grid.Column="1" /> </Grid> </ig:XamDialogWindow>
こんな感じになりました。
続いて、RecordFilterDropDownPopulating イベントでビルトインのダイアログ表示をキャンセルし、自作のダイアログを表示。
// カスタムダイアログが出るイベント void xgrid1_CustomFilterSelectionControlOpening(object sender, Infragistics.Windows.DataPresenter.Events.CustomFilterSelectionControlOpeningEventArgs e) { // 本来出るダイアログ自体はキャンセルする。 e.Cancel = true; // 現在のカスタムフィルタから範囲設定の情報を抽出 string pGreaterThanOrEqualTo = ""; string pLessThanOrEqualTo = ""; foreach (ICondition c in e.RecordFilter.Conditions) { // 現在のカスタムフィルタの登録されている条件を走査 if (((Infragistics.Windows.Controls.ComparisonCondition)(c)).Operator == ComparisonOperator.GreaterThanOrEqualTo) { // Fromの情報があった場合 pGreaterThanOrEqualTo = ((Infragistics.Windows.Controls.ComparisonCondition)(c)).Value.ToString(); } if (((Infragistics.Windows.Controls.ComparisonCondition)(c)).Operator == ComparisonOperator.LessThanOrEqualTo) { // Toの情報があった場合 pLessThanOrEqualTo = ((Infragistics.Windows.Controls.ComparisonCondition)(c)).Value.ToString(); } } // 自作ダイアログに設定 this.textBox1.Text = pGreaterThanOrEqualTo; this.textBox2.Text = pLessThanOrEqualTo; // 自作ダイアログの表示 xamDialogWindow1.Visibility = System.Windows.Visibility.Visible; }
ここでは、グリッドに登録されている現在のフィルタ条件を全てループ文で走査し、 From と To に対応する条件が見つかった場合は、ダイアログ内の対応する項目に設定しています。
最後に、自作ダイアログ内の OKボタン と Cancelボタン が押された際の処理を書けば完了です!
//OKボタン押下時 private void button1_Click(object sender, RoutedEventArgs e) { RecordFilter rf = xgrid1.FieldLayouts[0].RecordFilters["Name"]; for (int i = rf.Conditions.Count - 1 ; i >= 0 ; i--) { //一旦条件をクリアする if (((Infragistics.Windows.Controls.ComparisonCondition)(rf.Conditions)).Operator == ComparisonOperator.GreaterThanOrEqualTo || ((Infragistics.Windows.Controls.ComparisonCondition)(rf.Conditions)).Operator == ComparisonOperator.LessThanOrEqualTo) { rf.Conditions.Remove(rf.Conditions); } } //修正した条件を適用する。 if(textBox1.Text.Trim() != ""){ rf.Conditions.Add(new ComparisonCondition(ComparisonOperator.GreaterThanOrEqualTo, textBox1.Text)); } if(textBox2.Text.Trim() != ""){ rf.Conditions.Add(new ComparisonCondition(ComparisonOperator.LessThanOrEqualTo, textBox2.Text)); } //閉じる xamDialogWindow1.Visibility = System.Windows.Visibility.Hidden; } //Cancelボタン押下時 private void button2_Click(object sender, RoutedEventArgs e) { //閉じる xamDialogWindow1.Visibility = System.Windows.Visibility.Hidden; }
※上記の「条件を一旦クリアする」の箇所が SyntaxHighlighter の都合上?おかしな表示になっています。正しいコードは添付されているサンプルコードより取得下さいませ。
OKボタン が押された際は、グリッドの現在のカスタムフィルタの条件を全てクリアし、 From 及び To で入力があった場合はそれぞれ新たにカスタムフィルタ条件を追加しています。
完成!!
今回ご紹介したシナリオは、実際にお客様から問合せいただいて、ご案内をしたものです。ビルトインの機能だけでもかなり充実していますが、こういった独自の作り込みもできますので是非ご参考にしてみてください!
※今回のサンプルは こちら から!!
NetAdvantage トライアル版ダウンロード
NetAdvantage は無料トライアルを用意しています。是非一度お試し下さい。