仅当项目不重复时才将项目添加到ListView

时间:2016-05-16 00:08:26

标签: c# .net wpf winforms

我已经在这个轮子上旋转了几天!

尝试按进程名称添加当前正在运行的特定进程的MainWindowTitle,在此示例中为#34; notepad",添加到ListView。我已经弄清楚如何创建和添加项目,但现在我在ListView中有重复项。所以我想要做的只是在我的ListView中添加一个项目,如果它不是我的ListView上的确切项目。

相关信息:

- 我将尝试从(从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);
            }
        }

3 个答案:

答案 0 :(得分: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;
    }
}

假设MainWindow在其XAML中包含ListView UI XAML块。这显示了我认为您正在寻找的结果。基本上我已经移动了将视图模型添加到视图模型中的逻辑,并且在您的问题中将其添加到视图之外,这使得实现逻辑变得更简单。

答案 1 :(得分:0)

我能想到这个代码不起作用的唯一原因是ListViewItem不会重载equals运算符。如果是这种情况,那么当你调用Contains时,它会检查对象是否是同一个对象,因为你刚刚创建了新对象。为了确保唯一性,我将使用linq Any函数而不是Contains。 Linq任何检查是否有任何符合给定条件的元素。

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

答案 2 :(得分:0)

您实际上可以使用Process对象作为ListViewItem的DataContext。然后,使用Process.Id检查项目是否已添加。

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