2010-07-16 2 views
1

У меня есть приложение WPF, которое использует (в настоящее время) локальную базу данных для работы в качестве источника привязки. Используя инструменты Visual Studio 2010, у меня есть модель LINQ-SQL, которая действует как Datacontext для большинства форм.Связанная с WPF фильтрация/поиск данных

У меня есть UserControl с TextBox и Datagrid. Datagrid ItemSource устанавливается на событие UserControl.Loaded с таблицей. TextBox имеет событие, назначенное так, чтобы запрос выполнялся в базе данных при изменении текста, а ItemSource обновлялся по datagrid.

Проблема с этим - это время, необходимое для запроса базы данных. Поскольку я переназначаю источник данных DataGrid для каждого поиска.

  1. Должен ли я загружать все записи на UserControl Загрузка - есть способ загрузки записей асинхронно в BackgroundWorker или подобное?

  2. Нужно ли переназначить DataGrid ItemsSource после каждого поиска или это более эффективный способ фильтрации данных?

Спасибо. Лиам

<UserControl x:Class="Tracker.DocumentsView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid> 
     <DataGrid AutoGenerateColumns="False" Margin="12,34,12,50" Name="dataGrid1"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Binding="{Binding Path=ID}" Header="ID" /> 
       <DataGridTextColumn Binding="{Binding Path=Reference}" Header="Reference" /> 
       <DataGridTextColumn Binding="{Binding Path=Subject}" Header="Subject" /> 
      </DataGrid.Columns> 
     </DataGrid> 

     <TextBox HorizontalAlignment="Left" Margin="64,8,0,0" Name="txtSearchBox" VerticalAlignment="Top" Width="224" TextChanged="txtSearchBox_TextChanged" /> 
     <TextBlock Text="Search" HorizontalAlignment="Left" Margin="11,12,0,0" Name="label1" VerticalAlignment="Top" Height="23" /> 
    </Grid> 
</UserControl> 

Код:

using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

using Tracker.Model; 

namespace Tracker 
{ 
    /// <summary> 
    /// Interaction logic for DocumentsView.xaml 
    /// </summary> 
    public partial class DocumentsView : UserControl 
    { 
     private TrackerDataContext db; 

     public DocumentsView() 
     { 
      InitializeComponent(); 
      this.Loaded += new RoutedEventHandler(DocumentsView_Loaded); 
     } 

     void DocumentsView_Loaded(object sender, RoutedEventArgs e) 
     { 
      db = new TrackerDataContext(); 
      dataGrid1.ItemsSource = db.Documents; 
     } 

     private void txtSearchBox_TextChanged(object sender, TextChangedEventArgs e) 
     { 
      TextBox textbox = sender as TextBox; 
      if (textbox != null) 
      { 
       string searchstr = textbox.Text; 
       if (!string.IsNullOrEmpty(searchstr)) 
       { 
        var filtered = from document in db.Documents 
            where document.Subject.Contains(searchstr) 
             || document.Reference.Contains(searchstr) 
            select document; 

        dataGrid1.ItemsSource = filtered; 
       } 
       else 
       { 
        dataGrid1.ItemsSource = db.Documents; 
       } 
      } 
     } 
    } 
} 

ответ

5

Я думаю, вы должны загрузить все записи из базы данных в начале , а затем использовать ICollectionView.Filter на ItemsSource. Итак, вы не должны делать базы данных обработки

Вы должны wrtie что-то вроде этого

private void txtSearchBox_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     TextBox textbox = sender as TextBox; 
     if (textbox != null) 
     { 
      _searchstr = textbox.Text; 
      if (!string.IsNullOrEmpty(_searchstr)) 
      { 
       ICollectionView view = CollectionViewSource.GetDefaultView(ItemsSource); 
       view.Filter = new Predicate<object>(filter); 
      } 
     } 
    } 

    private bool filter(object item) 
    { 
     if(item.Subject.Contains(_searchstr) || item.Reference.Contains(searchstr)) 
     { 
      return true; 
     } 
     return false;   
    } 

Надеется, что это помогает, Нидала.

+0

Благодарим вас! :-) – tommed

+0

Небольшая коррекция, вам нужно только проверить NULL в _searchStr, иначе, как только вы начнете удалять искомые символы, список не будет заполнен обратно. – sonne

Смежные вопросы