2015-07-15 3 views
1

Эта проблема кажется простой. У меня есть TreeView, давайте назовем его MyTreeView, заселенный со всеми буквами дисков, так что TreeView выглядит следующим образом:
A: \
C: \
D: \
F: \
Проверка наличия древовидной черепицы

Как проверить, содержит ли treeview определенный элемент? Как дерево отображает его элементы? Я создал MessageBox, чтобы показать MyTreeView.Items.GetItemAt (1), и он идентифицирует пункт 1 как:
"System.Windows.Controls.TreeViewItem Заголовок: C: \ Items.Count: 1"

Try проще всего первое, что, очевидно, не работает:

if (MyTreeView.Items.Contains(@"C:\") 
{ 
    MessageBox.Show(@"Tree contains C:\"); 
} 

следующая проще всего было бы попробовать сделать TreeViewItem, похожее на то, что я хочу, что также не работает:

TreeViewItem myItem = new TreeViewItem(); 
myItem.Header = @"C:\"; 
if (MyTreeView.Items.Contains(myItem) 
{ 
    MessageBox.Show("Tree contains " + myItem.ToString()); 
} 

Просто убедиться, что я имел фундаментальное понятие права, я попробовал некоторые круговую логику, которая на самом деле делает работу:

var myItem = MyTreeView.Items.GetItemAt(1); 
if (MyTreeView.Items.Contains(myItem) 
{ 
    MessageBox.Show("Tree contains " + myItem.ToString()); 
} 

Какие выходы:
«Дерево содержит System.Windows.Controls.TreeViewItem Заголовок: C: \ Items.Count : 1 "

Что я делаю неправильно? Как проверить, содержит ли мое дерево что-то вроде «C: \»?

редактировать:
Код для построения дерева такова:
(в основном копировать и вставлять из Интернета)

 foreach (string myString in Directory.GetLogicalDrives()) 
     { 
      TreeViewItem item = new TreeViewItem(); 
      item.Header = myString; 
      item.Tag = myString; 
      item.FontWeight = FontWeights.Normal; 
      item.Items.Add(dummyNode); // this is (object)dummyNode = null 
      item.Expanded += new RoutedEventHandler(DWGFolder_Expanded); 
      item.Selected += new RoutedEventHandler(DWGFolder_Selected); 
      // the Expanded event is very similar, 
      // subitem.Header is the folder name (Testing), 
      // while subitem.Tag is the full path (C:\Testing) 
      MyTreeView.Items.Add(item); 
     } 

Поэтому в основном я пытаюсь соответствовать объекты TreeViewItem.

+0

Причина ваша вторая не работает, что ваш TreeView, очевидно, не будет содержать элемент, который вы только что создали. Ваш третий метод очень близок. Вы сказали, что это работает, почему бы не продолжать его строить? –

+0

Вы можете назначить объекту в своем древовидном представлении имя, а затем использовать '.FindName' - https://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.findname(v=vs.100). aspx – cdsln

ответ

4

Я считаю .Contains() будет проверять значение по ссылке, поскольку это не простой строковый объект. Это требует, чтобы вы выполняли итерацию каждого элемента, пока не получите элемент, соответствующий заголовку.

LINQ Пример

if (MyTreeView.Items.Cast<TreeViewItem>().Any(item => item.Header.ToString() == @"C:\")) 
    { 
     MessageBox.Show(@"Tree contains C:\"); 
    } 
+0

** «Полагаю, что .Contains() будет проверять значение по ссылке« ** Интересно. Я так не думал об этом, но это имеет смысл. В любом случае, ваше решение работает безупречно. Спасибо огромное! –

+0

Если itemCollection содержит тип значения, такой как строка, это будет просто проверка «newValue». Рад, что я мог помочь. – lamorach

+0

@lamorach String не является типом значений, даже если он ведет себя как таковой. Но теперь, когда вы упомянули об этом, я думаю, что в этом случае сопоставители равенства будут работать с «Содержит». Хорошая точка зрения. – almulo

1

Contains ищет тот же экземпляр внутри коллекции. Если у вас нет объекта, который вы хотите проверить уже, вы не можете использовать Contains.

Но вы можете использовать некоторый базовый запрос LINQ ... Добавить пространство имен LINQ к классу:

using System.Linq; 

Если элементы действительно только строки, а затем использовать этот запрос (EDIT - Хотя, в случае они просто Strings, ContainsРЕКОМЕНДУЕМОГО работа, так как их компараторы равенства не ведут себя, как у обычных ссылочных типов, но сравнивать по стоимости):

if (MyTreeView.Items.Cast<string>().Any(s => s == @"C:\")) 
{ 
    // Do stuff 
} 

Если ваши детали TreeViewItems, вы можете использовать это один:

if (MyTreeView.Items.Cast<TreeViewItem>().Any(i => i.Header.ToString() == @"C:\")) 
{ 
    // Do stuff 
} 

Но ваши предметы могут быть любой класс, мы не знаем, или ваш заголовок привязки может измениться ... Не зная, как вы добавляете элементов в TreeView, трудно дать вам лучшую альтернативу.

EDIT - Имейте в виду, что это будет искать только на первом уровне дерева. Если предмет, который вы ищете, находится где-то глубже, вам придется делать рекурсивный поиск. В этот момент лучше всего сохранить значения, хранящиеся где-то с самого начала.

+0

Я думаю, вы должны проверить строку с заголовком элементов. иначе это не сработает. –

+0

Ваш код не работает, потому что «Невозможно наложить объект типа System.Windows.Controls.TreeViewItem на тип System.String» , но я думаю, что вы на правильном пути. Спасибо за идею! –

+0

Элементы не возвращают список TreeViewItems, он возвращает фактические данные. Вот почему я сказал: «Если ваши предметы действительно просто Струны». Они также могут быть совершенно другим классом, если на то пошло ... – almulo

Смежные вопросы