2014-09-11 66 views
0

我創建了一個簡單的wmi查詢,然後創建一個自定義集合。 我已經添加了一個過濾器,它從文本更改事件的文本框中獲取字符串。 它按預期工作,但有1個主要缺點,每次嘗試過濾它實際上都在執行查詢。我希望它做的是存儲集合localy並對該局部變量進行操作,而不是一遍又一遍地執行wmi查詢。 我已經嘗試了多路方式,但目前爲止沒有運氣。 任何幫助將appriciated! :)c#wpf商店DataGrid收藏本地和過濾與文本框

這裏是1路我想...

主要CS:

using System; 
using System.Collections.Generic; 
using System.Windows; 
using System.Windows.Data; 

namespace myfilter 
{ 
    public partial class FilteringSample : Window 
    { 
     public FilteringSample() 
     { 
      InitializeComponent(); 

      myProcesses items = new myProcesses(); 
      lvUsers.ItemsSource = items.GetProcesses; 

      CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource); 
      view.Filter = UserFilter; 
     } 

     private bool UserFilter(object item) 
     { 
      if (String.IsNullOrEmpty(txtFilter.Text)) 
       return true; 
      else 
       return ((item as myProcess).Name.IndexOf(txtFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0); 
     } 

     private void txtFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) 
     { 
      CollectionViewSource.GetDefaultView(lvUsers.ItemsSource).Refresh(); 
     } 
    } 
} 

類CS:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Management; 
using System.Text; 
using System.Threading.Tasks; 

namespace myfilter 
{ 
    class myProcesses 
    { 
     public IEnumerable<myProcess> GetProcesses 
     { 
      get 
      { 
       ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process"); 
       ManagementObjectCollection processList = searcher.Get(); 
       myProcess myproc; 
       foreach (ManagementObject obj in processList) 
       { 
        if (obj != null) 
        { 
         myproc = new myProcess(); 
         try 
         { 
          myproc.Name = obj["Name"].ToString(); 
         } 
         catch { } 
         try 
         { 
          myproc.ID = obj["ProcessId"].ToString(); 
         } 
         catch { } 

         yield return myproc; 
        } 
       } 
      } 
     } 
    } 

    class myProcess 
    { 
     public string Name { get; set; } 
     public string ID { get; set; } 
    } 
} 

XAML:

<Window x:Class="myfilter.FilteringSample" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="FilteringSample" Height="200" Width="300"> 
    <DockPanel Margin="10"> 
     <TextBox DockPanel.Dock="Top" Margin="0,0,0,10" Name="txtFilter" TextChanged="txtFilter_TextChanged" /> 
     <DataGrid Name="lvUsers"> 

     </DataGrid> 
    </DockPanel> 
</Window 

>

回答

0

那麼想我是自己弄明白。 我存儲的數據在

ObservableCollection<> 

,並且讓我再次檢查本地過濾結果,並沒有重新推出的查詢。 所以這裏是修改後的代碼,如果有人有興趣(的變化只在主要的CS製造):

namespace filter 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     ObservableCollection<myProcess> myCollection; 
     public MainWindow() 
     { 
      InitializeComponent(); 

      myProcesses items = new myProcesses(); 
      myCollection = new ObservableCollection<myProcess>(); 
      foreach (myProcess localproc in items.GetProcesses) 
      { 
       myCollection.Add(localproc); 
      } 
      lvUsers.ItemsSource = myCollection; 

      CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(myCollection); 
      view.Filter = UserFilter; 
     } 

     private bool UserFilter(object item) 
     { 
      if (String.IsNullOrEmpty(txtFilter.Text)) 
       return true; 
      else 
       return ((item as myProcess).Name.IndexOf(txtFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0); 
     } 

     private void txtFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) 
     { 
      CollectionViewSource.GetDefaultView(myCollection).Refresh(); 
     } 
    } 

} 
0

您似乎遇到的問題是您正在UI(調度程序)線程上執行所有工作(查詢WMI)的事實。如果您希望UI在用戶使用該應用程序時保持響應,而不是「白屏」或凍結,則需要使用異步方法來查詢數據。

有.NET Framework的幾個部分可以幫助您與此:

  • TPL(任務<牛逼>)
  • BackgroundWorker的類,
  • Thread類,

是幾個例子,另外還有像Rx(Reactive Extensions for .Net)這樣的技術,它封裝併爲handl提供了一個非常好定義的API異步問題。

您選擇哪種解決方案過你將不得不應對來自後臺線程更新UI,有很多的如何做到這一點的SO例子。

過程引入異步執行到你的程序一般會增加任何代碼庫,尤其是UI代碼的複雜性,但這是成本,如果你希望你的應用程序從用戶的角度保持高性能。

畢竟,如果您不想使用異步方法,您可以將結果從myProcesses類中的WMI查詢緩存一段特定的時間,讓我們說1分鐘,這樣任何未來的請求都會返回這些結果而不是做另一個查詢,一旦過了1分鐘,您將清除緩存的結果,並且將來的查詢將針對WMI執行,並再次重複該過程。

+0

我想類似的東西到數據集上的ASP。例如,您可以查詢SQL Server,但將表存儲在數據集上並對數據集執行操作... – 2014-09-11 19:13:38