#事象
WPFアプリで、WindowにDataGridを設置した。Windowの初期化時に、DataGridの列のプロパティを操作しようとするとエラーが出た。
##エラー内容
System.ArgumentOutOfRangeException
インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。
パラメーター名:index
##詳細
表示したかったのはこちらの画面。DataGridが一覧表になっており、保存や削除のボタンがある。
xamlはこちら。
<Window x:Name="端末登録" x:Class="SkillAttacher.Admin.Terminals"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="端末登録" Height="700" Width="600" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" Icon="/SkillAttacher;component/rect3063.ico">
<WrapPanel>
<StackPanel>
<Label x:Name="Error" Content="" Margin="30,20,0,0" Foreground="Red"></Label>
<DataGrid x:Name="GridTerminals" HorizontalAlignment="Left" Margin="30,10,0,0" VerticalAlignment="Top" Height="570" Width="400" RenderTransformOrigin="0.5,0.5"
SelectionMode="Single" SelectionUnit="CellOrRowHeader" CanUserResizeColumns="False" CanUserReorderColumns="False" CanUserResizeRows="False" CanUserDeleteRows="False"
RowEditEnding="DataGrid_Edit" AddingNewItem="DataGrid_Edit" CanUserSortColumns="False">
<DataGrid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<TranslateTransform/>
</TransformGroup>
</DataGrid.RenderTransform>
</DataGrid>
</StackPanel>
<StackPanel>
<Button x:Name="Regist" Content="保存" HorizontalAlignment="Left" Height="65" Margin="30,395,0,0" VerticalAlignment="Top" Width="100" Click="Regist_Click"/>
<Button x:Name="Delete" Content="削除" HorizontalAlignment="Left" Height="65" Margin="30,20,0,0" VerticalAlignment="Top" Width="100" Click="Delete_Click"/>
<Button x:Name="Back" Content="戻る" HorizontalAlignment="Left" Height="45" Margin="30,40,0,0" VerticalAlignment="Top" Width="100" Click="Back_Click"/>
</StackPanel>
</WrapPanel>
</Window>
xaml.csはこちら(抜粋)。コンストラクタから呼び出したメソッドの中で、DataGridのColmunを操作する箇所でエラーが発生した。
/// <summary>
/// コンストラクタ
/// </summary>
public Terminals()
{
InitializeComponent();
SetData();
}
/// <summary>
/// データグリッドにデータをバインド
/// </summary>
private void SetData()
{
var ds = new DataSet();
try
{
conn = new SqlConnection(Define.CONN_STR);
conn.Open();
string qry = "SELECT * FROM Terminals WHERE IsDelete='False' ORDER BY TerminalDisplayOrder ASC;";
adapter = new SqlDataAdapter(qry, conn);
adapter.SelectCommand.CommandType = CommandType.Text;
adapter.Fill(ds);
}
catch (Exception ex)
{
// 省略
}
GridTerminals.ItemsSource = ds.Tables[0].DefaultView;
GridTerminals.Columns[0].Width = 150;
GridTerminals.Columns[1].Width = 210;
GridTerminals.Columns[0].Header = HEADER_TERMINAL_CD;
GridTerminals.Columns[1].Header = HEADER_TERMINAL_IP_ADDRESS;
}
データをDBから取得して、バインドしており、DataGridのItemsには数件のデータが入っている。しかしDataGridのColumns.Countは0になっている。
列数が0なのに第一列目を装飾しようとしたため、落ちてしまっていた。
#解決方法
/// <summary>
/// コンストラクタ
/// </summary>
public Terminals()
{
InitializeComponent();
//SetData();
ContentRendered += (s, e) => SetData();
}
画面がレンダリングされる前にDataGridの列を操作しようとしたことが原因。
ContentRenderdのイベントに問題のメソッドを追加し、レンダリング後に行うようにしたら、ちゃんと動いた。