GcSpreadGridがセル結合を含んでいると、コピー&ペーストの実行時に不正に非表示の行列を処理の対象に含める
対象製品
SPREAD for WPF 3.0J
状況
回避方法あり
詳細
GcSpreadGridが行結合や列結合などのセル結合を含んでいると、非表示の行列をまたいでセル範囲を選択しコピー&ペーストを実行した場合に、不正に非表示の行列を処理の対象に含めてしまいます。
例えば、「回避方法」に記載のサンプルコードで、RowSpan/ColumnSpanプロパティによるセル結合を有効にすると、非表示行のセルに値がペーストされます。本来はペーストされない動作が正しい動作となります。
例えば、「回避方法」に記載のサンプルコードで、RowSpan/ColumnSpanプロパティによるセル結合を有効にすると、非表示行のセルに値がペーストされます。本来はペーストされない動作が正しい動作となります。
- 15、16行目を非表示にします(Button_Clickイベント)。
- A列の14~17行目を範囲選択してCtrl+Cでコピーします。
- B列の14行目のセルを選択してCtrl+Vで貼り付けします。
- 15、16行目を表示します(Button_Clickイベント)。
- 非表示にしていた行のセルに値がペーストされます。
回避方法
コピー&ペーストを行う際に一時的にセルの結合を解除することで回避します。このとき、セル結合の状態を保存しておくために、独自に作成したSetRowSpan/SetColumnSpan関数により結合を行います。
◎サンプルコード(C#)
◎サンプルコード(C#)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
gcSpreadGrid1[13, 0].Text = "A14";
gcSpreadGrid1[14, 0].Text = "A15";
gcSpreadGrid1[15, 0].Text = "A16";
gcSpreadGrid1[16, 0].Text = "A17";
// RowSpan/ColumnSpanプロパティによるセル結合は使用しません。
//gcSpreadGrid1.Cells[0, 0].RowSpan = 10;
//gcSpreadGrid1.Cells[0, 0].ColumnSpan = 4;
// 独自に用意したSetRowSpan/SetColumnSpan関数により結合を行うことで回避します。
SetRowSpan(0, 0, 10);
SetColumnSpan(0, 0, 4);
gcSpreadGrid1.AddHandler(CommandManager.ExecutedEvent,
new ExecutedRoutedEventHandler(Spread_Executed), true);
gcSpreadGrid1.AddHandler(CommandManager.PreviewExecutedEvent,
new ExecutedRoutedEventHandler(Spread_PreviewExecuted), true);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
gcSpreadGrid1.Rows[14].IsVisible = !gcSpreadGrid1.Rows[14].IsVisible;
gcSpreadGrid1.Rows[15].IsVisible = !gcSpreadGrid1.Rows[15].IsVisible;
}
private readonly Dictionary_rowSpans = new Dictionary ();
private readonly Dictionary_columnSpans = new Dictionary ();
private void SetRowSpan(int row, int column, int value)
{
var key = new Int32Point { Row = row, Column = column };
if (value == 1 && _rowSpans.ContainsKey(key))
{
_rowSpans.Remove(key);
}
else
{
_rowSpans[key] = value;
}
gcSpreadGrid1.Cells[row, column].RowSpan = value;
}
private void SetColumnSpan(int row, int column, int value)
{
var key = new Int32Point { Row = row, Column = column };
if (value == 1 && _columnSpans.ContainsKey(key))
{
_columnSpans.Remove(key);
}
else
{
_columnSpans[key] = value;
}
gcSpreadGrid1.Cells[row, column].ColumnSpan = value;
}
private void Spread_Executed(object sender, ExecutedRoutedEventArgs e)
{
if (e.Command != ApplicationCommands.Copy &&
e.Command != ApplicationCommands.Paste)
{
return;
}
RecoverCellSpans();
}
private void RecoverCellSpans()
{
foreach (var item in _rowSpans)
{
var key = item.Key;
gcSpreadGrid1.Cells[key.Row, key.Column].RowSpan = item.Value;
}
foreach (var item in _columnSpans)
{
var key = item.Key;
gcSpreadGrid1.Cells[key.Row, key.Column].ColumnSpan = item.Value;
}
}
private void Spread_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
{
if (e.Command != ApplicationCommands.Copy &&
e.Command != ApplicationCommands.Paste)
{
return;
}
RemoveCellSpans();
}
private void RemoveCellSpans()
{
foreach (var item in _rowSpans)
{
var key = item.Key;
gcSpreadGrid1.Cells[key.Row, key.Column].RowSpan = 1;
}
foreach (var item in _columnSpans)
{
var key = item.Key;
gcSpreadGrid1.Cells[key.Row, key.Column].ColumnSpan = 1;
}
}
}
internal struct Int32Point : IEquatable
{
public int Row, Column;
public bool Equals(Int32Point other)
{
return Row == other.Row && Column == other.Column;
}
public override int GetHashCode()
{
return Row + (Column << 20);
}
public override bool Equals(object obj)
{
if (obj is Int32Point)
{
return Equals((Int32Point)obj);
}
return false;
}
}
キーワード
GcSpreadGrid