2013-06-23 3 views
0

Я пытаюсь создать систему фильтрации для DataGrid в WPF так же, как в ссылке -Фильтрация Datagrid привязываться к DataTable WPF

http://www.codeproject.com/Articles/42227/Automatic-WPF-Toolkit-DataGrid-Filtering

enter image description here

Я использую ту же библиотеку, что они но мне нужно привязать мой DataGrid к datatable ...

И там, где ошибка. Библиотека фильтров работает отлично, пока ItemSource является СПИСОК, но перестает работать, когда ItemSource является DataTable ...

Любые альтернативы или предложения ??? Рабочие примеры оценили ..

Я использую AutoColumnGeneration = True, так как я не знаю, сколько колонка мне нужно заполнить

+0

Вы пытались связать ItemSource с CollectionViewSource, взятым из DataTable? –

+0

На самом деле дело в том, что моя AutoColumnGeneration = TRUE .. , поскольку я не знаю точное количество столбцов, которые мне нужно заполнить .. Теперь любые предложения –

+0

Мне пришлось это делать раньше. Но у этого усилия был очень короткий плавкий предохранитель, поэтому я создал CollectionViewSource из строк и использовал заказной конвертер значений.Он работал отлично, но я уверен, что есть лучшие способы. Кроме того, в первом случае вы не можете использовать код, который обернут вокруг строго типизированных коллекций таблицей данных, потому что таблица данных использует массивы в штучной упаковке! –

ответ

3

Каждый 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, если это необходимо.

+0

Thanx много чувак !! –

+0

@RajatSuneja, пожалуйста, прочитайте это http://stackoverflow.com/help/someone-answers –

+0

Извините, Dude .. Должно быть, вышло из моего ума. Извините ... –