Использование Linq для фильтрации ComboBox.DataSource? - PullRequest
3 голосов
/ 21 марта 2010

в другой теме, я наткнулся на это очень элегантное решение Дарина Димитрова, чтобы отфильтровать источник данных одного ComboBox с выбором другого ComboBox: как отфильтровать комбинированный список в выпадающем списке, используя c #

combo2.DataSource = ((IEnumerable<string>)c.DataSource)
.Where(x => x == (string)combo1.SelectedValue);

Я хотел бы сделать то же самое, но для фильтрации по второму списку я бы хотел фильтровать по тексту TextBox.(По сути, вместо того, чтобы выбирать из второго ComboBox, пользователь просто вводит свой фильтр в TextBox).Однако оказалось, что это не так просто, как я надеялся.Я попытался выполнить следующее, но с треском провалился:

     cbWohndresse.DataSource = ((IEnumerable<DataSet>)ds)
            .Where(x => x.Tables["Adresse"].Select("AdrLabel LIKE '%TEST%'"));
        cbWohndresse.DisplayMember = "Adresse.AdrLabel";
        cbWohndresse.ValueMember = "Adresse.adress_id";

ds - это DataSet , который я хотел бы использовать в качестве отфильтрованного источника данных. «Адрес» - это один DataTable в этом наборе данных.Он содержит DataColumn "AdrLabel" .Теперь я хотел бы отображать только те «AdrLabel», которые содержат строку из пользовательского ввода.(В настоящее время% TEST% заменяет textbox.text.)

Приведенный выше код завершается ошибкой, поскольку лямбда-выражение не возвращает Bool.Но я уверен, что есть и другие проблемы (какой тип я должен использовать для IEnumerable? Теперь это DataSet, но Дарин использовал String. Но как я могу преобразовать DataSet в строку?

Да, я какКак бы много это ни звучало, мой опыт «ничтожен», и публично так. Поэтому, пожалуйста, прости мне мои довольно глупые вопросы.

Ваша помощь очень ценится, потому что я не могу решить это самостоятельно (пробовалуже тяжело).

Большое спасибо!

Pesche

PS Я использую только Linq для создания несложного фильтра для ComboBox (избегая просмотра). Остальноеоснован не на Linq, а на старом стиле Ado.NET (ds заполняется SqlDataAdapter), если это имеет какое-либо значение.

Ответы [ 2 ]

4 голосов
/ 21 марта 2010

LINQ мне не кажется очевидным решением здесь.Ваши данные уже загружены в структуру DataSet, поэтому вы должны иметь возможность сделать что-то вроде этого:

var adresse = ds.Tables["Adresse"];
adresse.DefaultView.RowFilter = "AdrLabel LIKE '%TEST%'";

cbWohndresse.DataSource = adresse;
cbWohndresse.DisplayMember = "AdrLabel";
cbWohndresse.ValueMember = "adress_id"
cbWohndresse.DataBind();

Для решения реальных проблем в вашем текущем коде:

  1. Если ds имеет тип DataSet, приведение к IEnumerable<DataSet> завершится неудачей.
  2. DataTable.Select возвращает массив строк, а не логическое значение.
  3. Игнорирование # 1 и# 2, ваш вызов Where() вернет ноль, один или несколько экземпляров DataSet, каждый из которых имеет таблицу с именем "Adresse", и хотя бы одна строка соответствует фильтру.Следовательно, вы в конечном итоге привязываете свой элемент управления представлением к набору DataSet экземпляров, которые не , что вам нужно.
1 голос
/ 21 марта 2010

Если вы хотите использовать LINQ, вам нужно добавить ссылку System.Data.DataSetExtensions. Затем вы можете запросить свой DataSet «linqish» способом.

Сообщение в блоге Запросы к DataSets - Введение в LINQ to DataSet Эрик Томпсон, руководитель Microsoft, является хорошим введением в LINQ to DataSets

Вот очень грубый пример:

XAML

<StackPanel>

    <TextBox x:Name="MyFilter" />

    <ComboBox x:Name="MyComboBox" 
              ItemsSource="{Binding}"
              DisplayMemberPath="AdrLabel" />

    <Button Click="OnFilterClick">Filter</Button>

</StackPanel>

Код позади

public partial class FilteredDataSet : Window
{
    public FilteredDataSet()
    {
        InitializeComponent();

        CreateDataContext();
        MyComboBox.DataContext = MyDataSet.Tables[0];
    }

    private DataSet MyDataSet { get; set; }
    private void CreateDataContext()
    {
        var ds = new DataSet();
        var dt = new DataTable( "Adresse" );
        ds.Tables.Add( dt );

        var dc = new DataColumn( "AdrLabel" );
        dt.Columns.Add( dc );

        DataRow dr = dt.NewRow();
        dr[0] = "one";
        dt.Rows.Add( dr );

        dr = dt.NewRow();
        dr[0] = "honed";
        dt.Rows.Add( dr );

        dr = dt.NewRow();
        dr[0] = "obiwone";
        dt.Rows.Add( dr );

        dr = dt.NewRow();
        dr[0] = "won";
        dt.Rows.Add( dr );

        MyDataSet = ds;

    }
    private void OnFilterClick( object sender, RoutedEventArgs e )
    {
        string filter = MyFilter.Text;

        var context = MyDataSet.Tables[0].AsEnumerable()
            .Where( dr => dr.Field<string>( "AdrLabel" ).Contains( filter ) )
            .Select( dr => dr.Field<string>( "AdrLabel" ) );

        MyComboBox.DisplayMemberPath = string.Empty;

        MyComboBox.DataContext = context;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...