DataGrid と ListView の間の双方向バインディングの処理の不一致を理解するのに苦労しています。説明のために、いくつかのプロパティを持つクラス DataItem と、DataGrid/ListView にバインドするための DataItems のリストがあります。
public class DataItem
{
public bool Flag { get; set; }
public int IntValue { get; set; }
public string StringValue { get; set; }
public List<DataItem> SubList { get; set; }
public DataItem()[...]
}
メインの DataItem オブジェクトを作成し、いくつかの追加の DataItem オブジェクトを SubList に追加します。メインの DataItem は含まれている Grid の DataContext に設定され、SubList は両方の ListView にバインドされます。
<ListView ItemsSource="{Binding Path=SubList}">
<ListView.View>
<GridView>
<GridViewColumn Header="Flag" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="FlagCheckBox" IsChecked="{Binding Path=Flag}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="String Value" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="StringTextBox" Text="{Binding Path=StringValue}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
そしてDataGridに:
<DataGrid ItemsSource="{Binding Path=SubList}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Flag" Width="SizeToCells">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="FlagCheckBox" IsChecked="{Binding Path=Flag}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="String Value" Width="SizeToCells">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="StringTextBox" Text="{Binding Path=StringValue}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
ListView と DataGrid の両方が SubList 項目を適切に表示します。ただし、UI でデータを変更し、ソースの DataItem.SubList を調べると、ListView は機能しますが、DataGrid は機能しません。ListView で変更が行われた場合は変更を確認できますが、 DataGrid、変更はありません。
そうしないと、値が正しく表示されません。しかし、何らかの理由で、双方向バインディングは ListView で機能し、UI で行われた変更をソース オブジェクトに戻しますが、DataGrid では機能しません。