トップ回答者
DataGridのItemsSourceプロパティにデータを格納して、表示が終わった後にイベントハンドラを呼び出す方法について

質問
回答
-
こんにちは。
そのDataGridView.csの実装がどうなっているかわからないのでこのケースに当てはまるかはわかりませんが
一般的なDataGridのお話として言えることは
DataGridRowは実際に描画される時までインスタンスは作られない
(AutoGenerateColumnsをTrueにしている場合は自動生成Columnも。)
ということです。
質問文のやりかただとすると、
あるはずの行や列が見つからなくてエラーになっているような気がしますので、
dataGridView1.DataSource = dt;
の後に
DataGrid.UpdateLayout();
を入れてあげるといけるんじゃないかと思います。
(DataGridView.csがUpdateLayoutメソッドをサポートしているかどうかはわかりませんが)- 回答としてマーク kawata_sotaro 2011年10月3日 1:00
2011年10月2日 13:00
すべての返信
-
質問が漠然としてましたので、ソースを張らせて頂きます。
string型の2次元配列からDataTable(自作のコード)を作成して、DataGridView(自作のコード、DataGridをラップしている)のDataSourceにセットして、表を表示し、セルに色を付けるところまでを一度に行いたいのですが、(1)のところで例外が発生してしまいます。どこを直せばよいのか教えてください。ちなみに、DataGridViewは、SilverlightからDataGridをSystem.Windows.Formsの、DataGridViewのように扱えるようにしたものです。
--------------------------------
Admin2.xaml
--------------------------------
<UserControl xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
x:Class="dg3371.Admin2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:MyDataGridView"
Width="800" Height="600"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Canvas x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Vertical">
<my:DataGridView HorizontalAlignment="Left" Margin="12,12,0,0"
x:Name="dataGridView1" VerticalAlignment="Top" Height="280" Width="500" />
<Button x:Name="Button1" Width="70" Height="30" Content="ロード"
Click="Button1_Click" />
<Button x:Name="Button2" Width="70" Height="30" Content="色付け"
Click="Button2_Click" />
</StackPanel>
</Canvas>
</UserControl>
--------------------------------
Admin2.xaml.cs
--------------------------------
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using MyDataGridView;
namespace dg3371
{
public partial class Admin2 : UserControl
{
public Admin2()
{
InitializeComponent();
}
private void Button1_Click(object sender, RoutedEventArgs e)
{
int i, j, i_max, j_max;
i_max = 7;
j_max = 5;
string[][] strs = new string[j_max][];
for (j = 0; j < strs.Length; j++)
strs[j] = new string[i_max];
for (j = 0; j < strs.Length; j++)
{
for (i = 0; i < strs[0].Length; i++)
{
strs[j][i] = string.Format("str[{0}][{1}]", j, i);
}
}
DataTable dt;
dt = new DataTable(strs);
dataGridView1.DataSource = dt;
while (true) ---------- (2)
{
if (dataGridView1.Columns.Count == i_max && dataGridView1.Rows.Count == j_max - 1)
{
Button2_Click(sender, e); ---------- (1)
break;
}
}
}
private void Button2_Click(object sender, RoutedEventArgs e)
{
dataGridView1.Rows[0].Cells[0].BackColor = Color.FromArgb(255, 255, 128, 128);
dataGridView1.Rows[1].Cells[1].BackColor = Color.FromArgb(255, 255, 0, 0);
dataGridView1.Rows[2].Cells[2].BackColor = Color.FromArgb(255, 255, 0, 0);
dataGridView1.Rows[3].Cells[3].BackColor = Color.FromArgb(255, 255, 0, 0);
}
}
}
(2)のwhile文を取り除いて、「ロード」ボタン、「色付け」ボタンを順番に押せば、問題なく動作します。おそらく、DataGridViewに表の表示が終わった直後のタイミングで(1)を呼び出せばうまく動くものと思いますが、表示が終わったことを何で知ればよいのか、その方法が分かりません。
発生する例外は、「KeyNotFoundExceptionはユーザーコードによってハンドルされませんでした」、場所は、DataGridView.cs の
private FrameworkElement GetGridCell(DataGridViewCell cell)
{
↓ここ
var element =
this.grid.Columns[cell.ColumnIndex].GetCellContent(this.rowContainer[cell.RowIndex]);
while (true)
{
if (element == null)
return null;
if (element is DataGridCell)
return element;
element = element.Parent as FrameworkElement;
}
}
です。2011年9月28日 8:49 -
こんにちは。
そのDataGridView.csの実装がどうなっているかわからないのでこのケースに当てはまるかはわかりませんが
一般的なDataGridのお話として言えることは
DataGridRowは実際に描画される時までインスタンスは作られない
(AutoGenerateColumnsをTrueにしている場合は自動生成Columnも。)
ということです。
質問文のやりかただとすると、
あるはずの行や列が見つからなくてエラーになっているような気がしますので、
dataGridView1.DataSource = dt;
の後に
DataGrid.UpdateLayout();
を入れてあげるといけるんじゃないかと思います。
(DataGridView.csがUpdateLayoutメソッドをサポートしているかどうかはわかりませんが)- 回答としてマーク kawata_sotaro 2011年10月3日 1:00
2011年10月2日 13:00 -
Uchidaさん、どうもありがとうございます。
早速試してみましたら、その方法で解決いたしました!!
ただ1つだけ気になったのは、
DataTable dt;
dt = new DataTable(strs);
dataGridView1.DataSource = dt;
dataGridView1.UpdateLayout();
Button2_Click(sender, e);はうまく動いたのですが、
DataTable dt;
dt = new DataTable(strs);
dataGridView1.DataSource = dt;
dataGridView1.UpdateLayout();
MessageBox.Show("TEST");とした場合、テーブルが表示される前に、"TEST"ダイアログが先に表示されてしまいます。
それの理由が良く分からないのですが、でも当初の目的は達成できましたので、これで解決といたします。
ありがとうございました。大変助かりました。m(__)m
2011年10月3日 1:10