12 / 12 / 1
Регистрация: 23.03.2014
Сообщений: 86
1
.NET 4.x

Предотвратить ввод одинаковых значений в ListView

28.03.2014, 10:48. Показов 1781. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
добрый день.

Есть такой код поиска в xml, со строкой ввода. Найденная инфа подгружается в ListView:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
int i = 0;
        string unicodeto, dirtto;
        private void ButtonSearch_Click(object sender, EventArgs e)
        {
            string unicodevalue = TextBoxSearch.Text;
            XDocument doc = XDocument.Load(DirtHDBKPath.Value);
            foreach (XElement el in doc.Root.Elements("dirtnode"))
            {
                if (el.Element("unicode").Value == unicodevalue)
                {
                    foreach (XElement elul in el.Elements())
                    {
                        if (elul.Name.ToString() == "dirt")
                        {
 
                            dirtto = elul.Value;
                            unicodeto = unicodevalue;
                        }
                     
                    }
                }
                
            }
            if (unicodeto != null)
            {
                ListViewFind.Items.Add(unicodeto);
                ListViewFind.Items[i].SubItems.Add(dirtto);
                ++i;
                unicodeto = null;
                dirtto = null;
            }
            else
            {
                MessageBox.Show("По запросу " + "'" + unicodevalue + "'" + " в справочнике загрязняющих веществ ничего не найдено!");
            }
 
  
        }
Подскажите, пожалуйста, как не допустить ввод одинаковых значений в ListView? Избежать дублирования...
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.03.2014, 10:48
Ответы с готовыми решениями:

Можно ли предотвратить ввод некоторых символов в TextBox c клавиатуры
Необходимо, чтобы например при вводе символа "@" ничего не происходило. Знаю как это сделать в...

Как предотвратить ввод числа, которое больше чем может вместить тип
void main() try{ int i; cin >> i; if (i>INT_MAX)throw range_error("sdfsdfdsf"); cout << i;...

Арифметика: При вычитании значений предотвратить отрицательный результат
Доброго времени суток! у меня такая проблема, при каждом нажатии кнопки из выделенной строки...

Данные в ListView вносятся два раза (получается 2 строки одинаковых данных)
Public Class Form1 Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As...

8
10 / 10 / 1
Регистрация: 25.03.2014
Сообщений: 19
28.03.2014, 11:00 2
Используйте множества
http://professorweb.ru/my/csha... /12_12.php
1
12 / 12 / 1
Регистрация: 23.03.2014
Сообщений: 86
28.03.2014, 19:21  [ТС] 3
respondent, а можно немного подробнее?

Добавлено через 4 часа 14 минут
наверное - нельзя...может есть другие варианты?
0
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
28.03.2014, 19:24 4
GarZa,
1. создаем свой класс для строк MyClass
2. загружаем данные в List<MyClass> list
3.
C#
1
2
3
4
foreach(var v in list.Distinct())
{
//тут заносим v  в listView
}
0
12 / 12 / 1
Регистрация: 23.03.2014
Сообщений: 86
28.03.2014, 19:26  [ТС] 5
нечто подобное я пытаюсь изобразить... но оно не допускает только последующий ввод:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 string[] FindArr = new string[50];
        int i;
        string unicodeto, dirtto;
        private void AddToLV()
        {
            
             foreach (string finded in FindArr)
                if (finded != dirtto)
                    {
 
                        int index = ListViewFind.Items.Add(unicodeto).Index;
                        ListViewFind.Items[index].SubItems.Add(dirtto);
                        FindArr[i] = dirtto;
                        i++;
                        break;
                    }
                   else
                    {
                        MessageBox.Show("Введеное значение уже присутствует в списке!");
                        break;
                    } 
               
        }
0
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
28.03.2014, 21:06 6
По поводу множества - сначала заносим в HasSet<T>, в котором дублирование элементов невозможно, все элементы по отношению к Equals() и GetHashCode() - разные.
C#
1
2
3
4
5
6
7
8
HashSet<string> allElements = new HashSet<string>();
foreach (XElement elul in el.Elements()) {
    // даже если некоторые из элементов совпадают - будет добавлен только один
    allElements.Add(elul.Name.ToString());
}
 
foreach (string name in allElements)
    ListViewFind.Items.Add(name);
1
12 / 12 / 1
Регистрация: 23.03.2014
Сообщений: 86
29.03.2014, 09:31  [ТС] 7
Спасибо вам огромное...сделал вот так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
private void ButtonSearch_Click(object sender, EventArgs e)
        {
 
            HashSet<string> allElements = new HashSet<string>();
            string unicodeto, dirtto;
            string unicodevalue = TextBoxSearch.Text;
            XDocument doc = XDocument.Load(DirtHDBKPath.Value);
            foreach (XElement el in doc.Root.Elements("dirtnode"))
            {
                if (el.Element("unicode").Value == unicodevalue)
                {
                    foreach (XElement elul in el.Elements())
                    {
                        if (elul.Name.ToString() == "dirt")
                        {
                            unicodeto = unicodevalue;
                            allElements.Add(elul.Value);
                            allElements.Add(unicodeto);
                            dirtto = elul.Value;
                            
                        }
 
                    }
                    foreach (string name in allElements)
                        ListViewFind.Items.Add(name);
                }
 
 
            }
       
        }
только в строке
C#
1
allElements.Add(elul.Name.ToString());
изменил...

но все равно дублирует, вообщем одинаково приятно...я тут об UnionWith SortedSet... но никак в толк не возьму - в какой момент заполняется второй множество, чтобы с ним потом объединение сделать..

и еще вопрос: как из этого массива выделять элементы? ну то есть в коде выше - оно все кидает в один столбец listview, а надо по двум красиво сделать...

Добавлено через 29 минут
инициализацию множества вынес за пределы метода - все равно не работает...вот, блин, заковыка..

Добавлено через 4 минуты
однако по дебагу множество заполняется корректно - повторов нету...
0
Администратор
Эксперт .NET
9602 / 4744 / 761
Регистрация: 17.04.2012
Сообщений: 9,592
Записей в блоге: 14
29.03.2014, 09:43 8
GarZa, может, повторы из-за того что вы добавляете элементы по 2 раза
C#
1
2
allElements.Add(elul.Value);
allElements.Add(unicodeto);
Что фактически
C#
1
2
allElements.Add(elul.Value);
allElements.Add(TextBoxSearch.Text);
Также повторения могут быть из-за непечатаемых символов, возможно, в конце elul.Value или TextBoxSearch.Text стоят символы перевода строки (\n), которые при отображении не видны, а строки из-за этого различаются.
0
12 / 12 / 1
Регистрация: 23.03.2014
Сообщений: 86
29.03.2014, 19:41  [ТС] 9
tezaurismosis, ведь в самом множестве (в процессе работы программы) повторов не наблюдается...ишь че..

Добавлено через 18 минут
победил через вычитание множеств:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
HashSet<string> allElements = new HashSet<string>();
        HashSet<string> allElements2 = new HashSet<string>();
        string unicodeto, dirtto;
        int i = 0;
        private void ButtonSearch_Click(object sender, EventArgs e)
        {
            string unicodevalue = TextBoxSearch.Text;
            XDocument doc = XDocument.Load(DirtHDBKPath.Value);
            foreach (XElement el in doc.Root.Elements("dirtnode"))
            {
                if (el.Element("unicode").Value == unicodevalue)
                {
                    foreach (XElement elul in el.Elements())
                    {
                        if (elul.Name.ToString() == "dirt")
                        {
                            unicodeto = unicodevalue;
                            allElements.Add(unicodeto);
                            dirtto = elul.Value;
                            allElements.ExceptWith(allElements2);
                            
                       }
 
                    }
 
                    try
                    {
                        foreach (string name in allElements)
                        ListViewFind.Items.Add(name);
                        allElements2.Add(ListViewFind.Items[i].Text);
                        ListViewFind.Items[i].SubItems.Add(dirtto);
                        i++;
                    }
                    catch
                    {
                        MessageBox.Show("Уже есть!");
                    }
                       
                    
                        
                }
 
 
            }
       
        }
все работает, как надо...но что-то меня смущает... даже не то, что множества надо обнулять при закрытии формы... даже не знаю..что-то тут явно не так...

есть мнения, господа?..

Добавлено через 50 минут
вот итоговая более упрощенная рабочая версия, мож кому сгодится:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
HashSet<string> AddElements = new HashSet<string>();
        HashSet<string> AddedElements = new HashSet<string>();
        string dirtto;
        int i = 0;
        private void ButtonSearch_Click(object sender, EventArgs e)
        {
            string unicodevalue = TextBoxSearch.Text;
            XDocument doc = XDocument.Load(DirtHDBKPath.Value);
            foreach (XElement el in doc.Root.Elements("dirtnode"))
            {
                if (el.Element("unicode").Value == unicodevalue)
                {
                    foreach (XElement elul in el.Elements())
                    {
                        if (elul.Name.ToString() == "dirt")
                        {
                            AddElements.Add(unicodevalue);
                            dirtto = elul.Value;
                            AddElements.ExceptWith(AddedElements);
                        }
 
                    }
                   
                        try
                        {
                            foreach (string name in AddElements)
                            ListViewFind.Items.Add(name);
                            AddedElements.Add(ListViewFind.Items[i].Text);
                            ListViewFind.Items[i].SubItems.Add(dirtto);
                            i++;
                        }
                        catch
                        {
                            MessageBox.Show("Данное вещество уже присутсвует в списке!");
                           
                        }
                  
 
               }
 
            }
       
        }
Добавлено через 24 минуты
tezaurismosis, знаете почему ничего не получалось? listview же, по идее очищать надо каждый раз, чтобы из множества данные вводить, а то выходило, что множеством заполнялось, а старые данные висели

вот код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
HashSet<string> allElements = new HashSet<string>();
        private void ButtonSearch_Click(object sender, EventArgs e)
        {
            string unicodevalue = TextBoxSearch.Text;
            XDocument doc = XDocument.Load(DirtHDBKPath.Value);
            foreach (XElement el in doc.Root.Elements("dirtnode"))
            {
                if (el.Element("unicode").Value == unicodevalue)
                {
                    foreach (XElement elul in el.Elements())
                    {
                        if (elul.Name.ToString() == "dirt")
                        {
                            allElements.Add(unicodevalue);
                            allElements.Add(elul.Value);
                            ListViewFind.Items.Clear();
                        }
 
                    }
                    foreach (string name in allElements)
                    ListViewFind.Items.Add(name);
               }
          
            }
 
        }
мне он нравится гораздо больше первых двух... только бы научиться еще содержимое множества раскидывать по сабитемам листвью

Добавлено через 8 часов 22 минуты
Путем долгого изучения MSDN (может не туда глядел), но так и не нашел, как абсолютно разные по смыслу строки, которые подгружаются вот тут:

C#
1
2
               allElements.Add(unicodevalue);
                            allElements.Add(elul.Value);
раскидать по двум разным столбцам. Все они ломятся во все контролы парно, но это и правильно.

Это натолкнуло на мысль сменить тактику, чтобы и решить проблему первого поста этого треда и разложить красиво на ListView. Сделал так: данные напрямую забиваются в ListView, если они есть в xml файле, и параллельно в обычный List. А при последующем вводе, сначала проверяется List, на предмет повторяемости, и если там нет - вводится далее в ListView:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
List<string> allElements = new List<string>();
        private void ButtonSearch_Click(object sender, EventArgs e)
        {
            string unicodevalue = TextBoxSearch.Text;
            XDocument doc = XDocument.Load(DirtHDBKPath.Value);
            foreach (XElement el in doc.Root.Elements("dirtnode"))
            {
               
                    if (el.Element("unicode").Value == unicodevalue)
                    {
                        foreach (XElement elul in el.Elements())
                        {
                            
                            if (elul.Name.ToString() == "dirt")
                            {
                                if (allElements.Contains(unicodevalue))
                                {
                                    MessageBox.Show("Данное вещество уже выбрано!");
                                    return;
                                }
                                else
                                {
                                    int i = ListViewFind.Items.Add(unicodevalue).Index;
                                    ListViewFind.Items[i].SubItems.Add(elul.Value);
                                    allElements.Add(ListViewFind.Items[i].Text);
 
                                }
                            }
                       }
                       
                    }
                   
               }
       }
Еще один из вариантов решения проблемы
1
29.03.2014, 19:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.03.2014, 19:41
Помогаю со студенческими работами здесь

Ввод размера матрицы и ввод ее значений
Нужно что бы выводилось (это не проблема) окно в котором вводилось размерность матрицы ну например...

Ввод данных непосредственно в ListView
Здравствуйте. Можно ли сделать так, чтоб данные в ячейки listview вносились из интерфейса...

Ограничение на ввод одинаковых символов
Нужно сделать ограничение на ввод более 8 одинаковых символов в текстбоксе,то есть если больше 8...

SQLite and ListView. Ввод и вывод данных
Здравствуйте. Пишу программу(кто бы мог подумать). Есть подозрения, что данные в БД вбиваются не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru