セル内容の編集操作以外で値が変更された場合にキャンセルする

最強の表計算・グリッドコントロールとして多くの開発現場で採用されてきたSPREAD(スプレッド)。この記事ではWPFプラットフォームに対応した「SPREAD for WPF 2.0J」の機能を紹介します。

MVVMパターンが最適か?

WPFの開発で推奨されるMVVMパターンについて、以下の記事で紹介しています。

ただ、実際のところMVVMパターンと、コードビハインドでUIイベントを実装したイベントドリブン型の実装との間で悩む開発者の方も少なくありません。

MVVMのビュー(View)とビューモデル(ViewModel)間のやり取りに、バインディングやコマンドを用いてそれぞれの独立性を維持するよう試みるものの、時にはコードビハインドの簡潔な記述で実現する方法が有効に思える、そういうこともあるようです。
開発における多くの課題と同じく、MVVMパターンもケースバイケースで、絶対的な適用方法は存在しないと言えます。

MVVMパターンで利用するイベント

SPREAD for WPFのイベントは、MVVMパターンで使うことを想定したUIイベントとして提供しているものもあります。
以下は、2.0Jで機能追加されたイベントです。

イベント 説明
Filteredイベント フィルタリングで発生する
CellValueChangingイベント セル値の変更直前に発生する
CellValueChangedイベント セル値の変更後に発生する

セル値が変更した時のイベント

この中から、CellValueChangingCellValueChangedイベントを解説します。
通常、このように命名されたイベントは以下の違いを持たせます。

イベント 説明
~Changing 変更直前に発生し
イベント引数のCancelプロパティで変更をキャンセルできる
~Changed 変更後に発生する

また、SPREADのセル値の変更には、ユーザーがセルを編集する以外に、以下のような方法があります。

  • コーディングでセル値を変更する
  • セル範囲を選択し[Delete]キーで値をクリアする
  • セル範囲を選択し[Ctrl]+[X]キーで値を切り取る
  • クリップボードから値を貼り付ける
  • 数式が設定されたセルで計算結果が変更される

ユーザーがセルを編集した場合は、編集直前と編集後でCellEditEndingおよびCellEditEndedイベントが発生します。

しかし、選択したセル範囲の値が[Delete]キーでクリアされた場合など、セルの編集以外で値が変更された場合、CellEdit~イベントは発生しません。
そこで、セルの編集以外でも値が変更されたときに発生するイベントとして、CellValueChangingおよびCellValueChangedイベントを提供しています。

セル編集以外で値を変えた場合に変更をキャンセル

以下、CellValueChangingイベントのサンプルコードです。
このサンプルコードでは、セルの編集以外で値が変更された場合、変更をキャンセルします。

XAML
<sg:GcSpreadGrid x:Name='gcSpreadGrid1' 
      CellValueChanging='gcSpreadGrid1_CellValueChanging'/>
Visual Basic
Private Sub gcSpreadGrid1_CellValueChanging(sender As Object, e As GrapeCity.Windows.SpreadGrid.CellValueChangingEventArgs)
Dim row As Integer = e.Row, col As Integer = e.Column
Console.WriteLine(String.Format("セル[{0},{1}]を変更します。", row, col))
If Not gcSpreadGrid1(e.Row, e.Column).IsEditing Then
Console.WriteLine(String.Format("「{0}」から「{1}」は編集による変更ではありません、値変更をキャンセルします。", e.OldValue, e.NewValue))
 '値変更をキャンセルします
e.Cancel = True
End If
End Sub
C#
private void gcSpreadGrid1_CellValueChanging(object sender, GrapeCity.Windows.SpreadGrid.CellValueChangingEventArgs e)
{
int row = e.Row, col = e.Column;
Console.WriteLine(string.Format("セル[{0},{1}]を変更します。", row, col));
if(!gcSpreadGrid1[e.Row, e.Column].IsEditing)
{
Console.WriteLine(string.Format("「{0}」から「{1}」は編集による変更ではありません、値変更をキャンセルします。", e.OldValue, e.NewValue));
//値変更をキャンセルします
e.Cancel = true;
}
}

CellValueChangingおよびCellValueChangedイベントの詳細は製品ヘルプ「編集とイベント」に記載があります。

SPREAD for WPFの機能を体感

.NET FrameworkのClick Once機能を利用したデモを公開しています。
Windows PCにWebサイトからインストールして、SPREAD for WPFの機能を実際にお試しいただけます。

\  この記事をシェアする  /