Q074. XamDataGrid でセル編集と同時にレコードを確定するには?

A.XamDataGrid.UpdateMode プロパティでいくつかのモードを指定できるようですが、残念ながら UpdateMode 列挙体の記述を見る限り、編集と同時にレコードをコミットするモードはないようです。

メンバ 解説
OnRecordChangeOrLostFocus ユーザーがレコードのセルを変更した後、別のレコードを起動するか、または DataPresenterBase がフォーカスを失うと、DataSource が更新されます。
OnRecordChange ユーザーがレコードのセルを変更した後、別のレコードを起動すると、DataSource が更新されます
OnCellChangeOrLostFocus ユーザーがセルを変更した後、編集モードを終了するか、または Infragistics.Windows.DataPresenter.DataPresenterBase がフォーカスを失うと、DataSource が更新されます。
OnCellChange ユーザーがセルを変更した後、編集モードを終了すると DataSource が更新されます。
OnUpdate DataPresenterCommands.CommitChangesToAllRecords または DataPresenterCommands.CommitChangesToActiveRecord コマンドが実行される場合に限って DataSource が更新されます。


これを読むと、唯一 OnUpdate のみが DataPresenterCommands.CommitChangesToAllRecords を使えばコミットできるようですが、使い方がどうもよく判りません。しかし XamDataGrid.CellChanged イベント内で

e.Cell.Record.SetCellValue(e.Cell.Field, e.Editor.Value, true);

を実行すればOKとの情報を得ましたので、Interactivity.TriggerBase を継承したトリガーを作ってみました。


C#

using System.Windows.Interactivity;
using Infragistics.Windows.DataPresenter;
using Infragistics.Windows.DataPresenter.Events;

namespace MyApp {

	public class XamDataGridCommitCellChangedTrigger : TriggerBase<XamDataGrid> {

		protected override void OnAttached() {
			base.OnAttached();
			AssociatedObject.CellChanged += AssociatedObject_CellChanged;
		}

		protected override void OnDetaching() {
			base.OnDetaching();
			AssociatedObject.CellChanged -= AssociatedObject_CellChanged;
		}

		void AssociatedObject_CellChanged(object sender, CellChangedEventArgs e) {

			var grid = AssociatedObject as XamDataGrid;
			if (grid != null) {
				e.Cell.Record.SetCellValue(e.Cell.Field, e.Editor.Value, true);
			}
		}
	}
}


VB

Imports System.Windows.Interactivity
Imports Infragistics.Windows.DataPresenter
Imports Infragistics.Windows.DataPresenter.Events

Public Class XamDataGridCommitCellChangedTrigger
	Inherits TriggerBase(Of XamDataGrid)

	Protected Overrides Sub OnAttached()
		MyBase.OnAttached()
		AddHandler AssociatedObject.CellChanged, AddressOf AssociatedObject_CellChanged
	End Sub

	Protected Overrides Sub OnDetaching()
		MyBase.OnDetaching()
		RemoveHandler AssociatedObject.CellChanged, AddressOf AssociatedObject_CellChanged
	End Sub

	Private Sub AssociatedObject_CellChanged(sender As Object, e As CellChangedEventArgs)
		Dim grid = TryCast(AssociatedObject, XamDataGrid)
		If (grid IsNot Nothing) Then
			e.Cell.Record.SetCellValue(e.Cell.Field, e.Editor.Value, True)
		End If
	End Sub
End Class


で、XAML では以下のように使います。

<igDP:XamDataGrid >
	<i:Interaction.Triggers>
		<myapp:XamDataGridCommitCellChangedTrigger />
	</i:Interaction.Triggers>
</igDP:XamDataGrid >


Interactivity.TriggerBase の使い方に関しては、以下のサイトを参考にさせて頂きました。

関連記事Invoke Command When ENTER Key Is Pressed In XAML


System.Windows.Interactivity に定義されてる Trigger 関連のクラスについては、@ugaya40さんの以下のエントリも参考になりそうです。

関連記事MVVMパターンでViewModelからViewを操作したい


#まだまだ勉強中〜


WPF FAQ の目次に戻る