インフラジスティックス・ジャパン株式会社Blog

インフラジスティックス・ジャパン株式会社のチームメンバーが技術トレンド、製品Tips、サポート情報からライセンス、日々の業務から感じることなど、さまざまなトピックについてお伝えするBlogです。

XamDataGridによる複数セルの編集

複数のセルを同時に同じ値で編集する必要に迫られたことはありますか? この投稿はそんなあなたのためのものです。 今日、Infragisticsフォーラムを巡回していたら、XamDataGridの複数セル編集の実装に関する質問を見かけました。 古い投稿でしたが、すぐに解決策が頭に浮かびました。 そこで、この一般的なニーズに対する簡単な解決策を投稿してみようと思いました。

この記事の原文は以下よりご確認いただけます。
Brian Lagunas / Tuesday, February 28, 2012
Multi-Cell Editing with the XamDataGrid

NetAdvantage for WPF 11.2リリースに含まれるXamDataGridを使用します。 まず、新しいWPFアプリケーションを作成し、XamDataGridをMainWindowにドラッグしてみましょう。

<Grid>
    <igDP:XamDataGrid x:Name="_xamDataGrid">
    </igDP:XamDataGrid>
</Grid>

それでは、XamDataGridのデータソースとして使用するデータを作成しましょう。 今回は、以下のようなPersonクラスを使用することにしました。 INotifyPropertyChangedインターフェイスを実装していることに注目してください。

public class Person : INotifyPropertyChanged
{
    private string _firstname;
    public string FirstName
    {
        get { return _firstname; }
        set
        {
            _firstname = value;
            OnPropertyChanged("FirstName");
        }
    }

    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set
        {
            _lastName = value;
            OnPropertyChanged("LastName");
        }
    }

    private int _age;
    public int Age
    {
        get { return _age; }
        set
        {
            _age = value;
            OnPropertyChanged("Age");
        }
    }

    public static ObservableCollection<Person> GenerateSampleData()
    {
        ObservableCollection<Person> _people = new ObservableCollection<Person>();

        for (int i = 0; i < 25; i++)
        {
            _people.Add(new Person() { FirstName = String.Format("First {0}", i), LastName = String.Format("Last {0}", i), Age = i * 2 });
        }

        return _people;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

ご覧の通り、XamDataGridのダミーデータを生成するための静的メソッドも追加しています。 今のところ、このような感じです。

List<Cell> _cells = new List<Cell>();

public MainWindow()
{
    InitializeComponent();
    _xamDataGrid.DataSource = Person.GenerateSampleData();
}

では、複数セル編集機能の計画を立てます。

  1. ユーザーは編集するセルを選択します。
  2. ユーザーは複数セル編集機能を有効にします。
  3. ユーザーは値を入力します。
  4. 値は選択されたすべてのセルで更新されます。
機能実装

XamDataGridでセル選択を有効にするには、FieldSetting.CellClickActionをSelectCellに、FieldLayoutSettings.SelectionTypeCellをExtendedに設定するだけです。

<Grid>
    <igDP:XamDataGrid x:Name="_xamDataGrid">
        <igDP:XamDataGrid.FieldLayoutSettings>
            <igDP:FieldLayoutSettings SelectionTypeCell="Extended" />
        </igDP:XamDataGrid.FieldLayoutSettings>
        <igDP:XamDataGrid.FieldSettings>
            <igDP:FieldSettings CellClickAction="SelectCell" />
        </igDP:XamDataGrid.FieldSettings>
    </igDP:XamDataGrid>
</Grid>

どの時点で複数セル編集機能を有効にするかを決める必要があります。 この例では、キーボードのF2キーが押されたときだけ、複数セル編集機能を有効にすることにします。 この機能をいつ有効にするかについては、他にもルールが考えられますが、この記事ではF2ルールで問題ないでしょう。

ユーザーがF2キーを押したときにXamDataGrid.PreviewKeyDownイベントを処理し、選択したセルをリストに格納する必要があります。 これは、編集中にどのセルの選択状態を継続し、新しい値で更新させるかを知るために行います。 XamDataGrid.EditModeStartingイベントの発生よりも前に選択されたセルにアクセスする必要があるため、PreviewKeyDownイベントを使用します。

private void XamDataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
    XamDataGrid grid = sender as XamDataGrid;
    if (e.Key == Key.F2)
    {
        foreach (var item in grid.SelectedItems.Cells)
        {
            _cells.Add(item);
        }
    }
}

F2キーが押された直後にXamDataGridは編集モードに入り、XamDataGrid.EditModeStartingイベントが発生します。 ここで、選択されたすべてのセルをループして選択状態を再設定します。 これを行わなければ、選択されたセルは編集モードになると非選択になってしまいます。 これはまた、どのセルが更新されるかをユーザーに視覚的に示す目印にもなります。

private void XamDataGrid_EditModeStarting(object sender, Infragistics.Windows.DataPresenter.Events.EditModeStartingEventArgs e)
{
    foreach (var cell in _cells)
    {
        cell.IsSelected = true;
    }
}

ユーザーが値を入力し、編集を確定した後、XamDataGrid.EditModeEndingイベントが発生します。 ここで、選択されたセルをループし、リフレクションを使って対応するCell.Record.DataItemの更新するプロパティを見つけます。 すべてのセルが更新された後、選択セルのリストをクリアします。

private void XamDataGrid_EditModeEnding(object sender, Infragistics.Windows.DataPresenter.Events.EditModeEndingEventArgs e)
{
    if (_cells.Count > 0)
    {
        foreach (var cell in _cells)
        {
            cell.Record.DataItem.GetType().GetProperty(cell.Field.Name).SetValue(cell.Record.DataItem, e.Editor.Value, null);
        }
        _cells.Clear();
    }
}

以上です。 出来上がったのがこちらです。

ソースコードはこちらからダウンロードしてください