Каждый DataRow в таблице содержит плоский массив объектов, тип которых доступен только извлекая его из массива DataColumns. Поскольку все в массиве помещается в коробку, библиотека, которая опирается на строго типизированную коллекцию, такую как 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));
}
}
}
Конструктор принимает DataTable и использует строки в качестве обязательного источника к CollectionView. Поскольку 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>
Это DataGrid, чье ItemsSource привязано к CollectionView, который был объявлен и назначен в ViewModel. Каждый столбец данных передается через преобразователь вместе с параметром, который сообщает конвертеру, что ему нужно делать.
В довершение все прочь, вот конвертер ...
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 и срочную ситуацию. Все в кодировке занимает около часа. Заметим также, что моя привязка к Строкам, но вы также можете привязать к DefaultView, если это необходимо.
Вы пытались связать ItemSource с CollectionViewSource, взятым из DataTable? –
На самом деле дело в том, что моя AutoColumnGeneration = TRUE .. , поскольку я не знаю точное количество столбцов, которые мне нужно заполнить .. Теперь любые предложения –
Мне пришлось это делать раньше. Но у этого усилия был очень короткий плавкий предохранитель, поэтому я создал CollectionViewSource из строк и использовал заказной конвертер значений.Он работал отлично, но я уверен, что есть лучшие способы. Кроме того, в первом случае вы не можете использовать код, который обернут вокруг строго типизированных коллекций таблицей данных, потому что таблица данных использует массивы в штучной упаковке! –