2016-05-16 136 views
2

我一直在旋轉我的輪子在這個天!僅當項目不重複時纔將項目添加到ListView中

試圖將當前正在運行的特定進程的進程名(在此示例中爲「記事本」)添加到ListView中。我已經想出瞭如何創建和添加項目,但現在我在我的ListView中有重複項。所以我想要做的只是添加一個項目到我的ListView,如果它不作爲我的ListView上的確切項目存在。

相關信息:

-there會多,我試圖從(從1到9)捕捉MainWindowTitle相同的過程,但他們都有一個唯一的ID。

,高級別的MainWindowTitle會有所不同

這裏是我到目前爲止,我不能讓LINQ的工作,我不知道是否會有一種方法,使foreach循環,防止重複。

我感謝任何幫助!

Process[] processList = Process.GetProcessesByName("notepad"); 
    foreach (Process process in processList) 
    { 
     ListViewItem item = new ListViewItem(); 
     item.Content = process.MainWindowTitle; 
     item.Tag = process; 

     if (listView.Items.Contains(item)) 
     { 
      MessageBox.Show("Duplicate"); 
     } 
     else 
     { 
      MessageBox.Show("New Item!"); 
      listView.Items.Add(item); 
     } 

編輯1:仍在添加重複的項目

 Process[] processList = Process.GetProcessesByName("notepad"); 
     foreach (Process process in processList) 
     { 
      ListViewItem item = new ListViewItem(); 
      item.Content = process.MainWindowTitle; 

      item.DataContext = process; 

      var itemz = listView.Items.Cast<ListViewItem>().ToList().Where(x => x.DataContext == process); 

      if (listView.Items.Contains(itemz)) 
      { 
       MessageBox.Show("Duplicate"); 
      } 
      else 
      { 
       MessageBox.Show("New Item!"); 
       listView.Items.Add(item); 
      } 

EDIT2:更緊密的,我希望,仍然在增加重複

 Process[] processList = Process.GetProcessesByName("notepad"); 
     foreach (Process process in processList) 
     { 
      ListViewItem item = new ListViewItem(); 
      item.Content = process.MainWindowTitle; 

      item.DataContext = process; 

      var itemz = listView.Items.Cast<ListViewItem>().ToList().Where(x => (x.DataContext as Process).Id == process.Id); 

      if (itemz == null) 
      { 
       MessageBox.Show("Duplicate"); 
      } 
      else 
      { 
       MessageBox.Show("New Item!"); 
       listView.Items.Add(item); 
      } 
     } 

回答

0

我能想到這個代碼不工作的唯一原因ListViewItem不會重載equals運算符。如果是這種情況,那麼當你調用Contains時,它會檢查對象是否是同一個對象,因爲你只是創建了一個新對象。爲了保證唯一性,我會使用linq Any函數代替Contains。 Linq Any檢查是否有任何符合給定條件的元素。

if (listView.Items.Contains(item))//replace this 
if(listView.Items.Any(x=>x.Content == item.Content))//with this 
+0

謝謝你的想法,在另一個論壇上的某個人建議,不幸的是,'ItemCollection'不包含'Any'的定義。 –

+0

你是否在使用System.Linq; Linq函數需要使用語句來工作。 –

+0

是的,使用System.Linq; 仍然是一個新的程序員總的來說,新的c#,但.contains似乎稱爲'對象',我相信這就是爲什麼任何不可用 –

0

實際上,您可以使用Process對象作爲ListViewItem的DataContext。然後,使用Process.Id來檢查項目是否已被添加。

var item = listview.Items.Cast<ListViewItem>().ToList().Where(x => x.DataContext == theProcess); 
+0

我非常感謝一個例子,我無法絆倒if語句與以上信息 –

+0

我已添加示例。 – tgpdyk

+0

對c#來說還是很新的,這看起來很有前途,但我不確定如何使用它。我是否用這個替換了一些行,或者這應該是我的新if語句? 另外,'theProcess'代表什麼與我的代碼有關? 我真的很感謝你的幫助! –

1

而不是手動填充ListView與項目創建一個包含要顯示的唯一窗口標題的ObservableCollection<string>。然後將ListView.ItemsSource設置爲此屬性。在這個支持收集只是確保只添加一些東西,如果它是不同的。因此,像這樣:

視圖模型

public class ValuesViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public ObservableCollection<string> WindowTitles { get; private set; } 

    public ValuesViewModel() 
    { 
     WindowTitles = new ObservableCollection<string>(); 
    } 

    public void AddTitleIfUnique(string title) 
    { 
     if (!WindowTitles.Contains(title)) 
      WindowTitles.Add(title); 
    } 
} 

UI XAML

<ListView ItemsSource="{Binding WindowTitles}"/> 

UI代碼隱藏

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

     var viewModel = new ValuesViewModel(); 
     viewModel.AddTitleIfUnique("Testing"); 
     viewModel.AddTitleIfUnique("Testing Again"); 
     viewModel.AddTitleIfUnique("Testing Again"); 
     DataContext = viewModel; 
    } 
} 

WHE假設MainWindow在其XAML中包含ListView UI XAML塊。這顯示了我認爲你正在尋找的結果。基本上,我已經將添加邏輯添加到了視圖模型中,如果在視圖模型中添加了獨特功能,並且像您在問題中所看到的一樣,這使得實現邏輯更加簡單。