テーブル内の各 DataRow には、DataColumns 配列から抽出することによってのみ型にアクセスできるオブジェクトのフラットな配列が含まれています。Array 内のすべてがボックス化されているため、List of T のような厳密に型指定されたコレクションに依存するライブラリは互換性がありません。それが機能しない理由を説明するはずです。
あなたはそれが緊急だと書いていて、私は非常に短いヒューズのプロジェクトで一度同じタイプのことをしなければならなかったので、私のアプローチの概要を説明します. この回答は緊急の場合のみです。
ここにViewModelがあります...
public class ViewModel : INotifyPropertyChanged
{
public CollectionView MyCollectionView { get; set; }
public ViewModel(DataTable dataTable)
{
MyCollectionView = CollectionViewSource.GetDefaultView(dataTable.Rows) as CollectionView;
if (MyCollectionView != null)
{
MyCollectionView.Filter = o => (o as DataRow).ItemArray[0].ToString().Contains("2");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
Constructor は DataTable を受け取り、CollectionView へのバインディング ソースとして Rows を使用します。CollectionView にはフィルター処理と並べ替えのプロパティが組み込まれているため、バインディング ソースとして使用するのに最適なツールです。また、示されているように、コンストラクターは、開始に役立つ例のフィルターを追加します。
ユーザーにデータを表示するには、次の Xaml を検討してください...
<DataGrid ItemsSource="{Binding MyCollectionView}"
AutoGenerateColumns="False"
CanUserSortColumns="True"
IsReadOnly="True"
>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding ., Converter=
{db:DbConverter}, ConverterParameter=PersonName}"/>
<DataGridTextColumn Header="Address" Binding="{Binding ., Converter=
{db:DbConverter}, ConverterParameter=PersonAddress}"/>
</DataGrid.Columns>
</DataGrid>
これは、ViewModel で宣言および割り当てられた CollectionView に ItemsSource がバインドされている DataGrid です。データの各列は、コンバーターに何をする必要があるかを伝えるパラメーターと共にコンバーターを通過します。
すべてを締めくくるために、ここにコンバーターがあります...
public class DbConverter : MarkupExtension, IValueConverter
{
private static readonly Dictionary<object, int> ParameterToColumnMapping;
static DbConverter()
{
ParameterToColumnMapping = new Dictionary<object, int>
{
{"PersonName", 0}, {"PersonAddress", 1}
};
}
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
DataRow dr = value as DataRow;
if (dr != null)
{
if (ParameterToColumnMapping.ContainsKey(parameter))
{
return dr.ItemArray[ParameterToColumnMapping[parameter]];
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return null;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
これにより、DataTable と緊急の状況が発生したときに、フィルタリングと表示を元に戻すことができます。コーディングにはすべて約 1 時間かかります。また、鉱山はRowsにバインドしますが、必要に応じてDefaultViewにバインドすることもできます。