2010-07-16 82 views
1

我有一個WPF應用程序,它使用(當前)本地數據庫充當綁定源。使用Visual Studio 2010工具我有一個LINQ-SQL模型,它充當大多數表單的Datacontext。WPF數據綁定數據網格過濾/搜索

我所擁有的是帶有TextBox和Datagrid的UserControl。 DataGrid ItemSource在帶有表格的UserControl.Loaded事件上設置。 TextBox有一個分配的事件,以便在文本更改並且在DataGrid上更新ItemSource時對數據庫執行查詢。

這個問題是查詢數據庫花費的時間。我正在爲每個搜索重新分配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

我想你應該在開始時 加載所有從數據庫中的記錄,然後在使用的ItemsSource ICollectionView.Filter。 那麼接下來你就不必做數據庫事務

你應該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 2013-01-10 09:48:02

+0

小的更正,你只需要檢查_searchStr中的NULL,否則一旦你開始移除搜索到的字符,這個列表不會回填。 – sonne 2015-01-14 18:11:56