Рейтинг:
24
Eric Lynch
Должно сработать следующее:
private static TreeNode FindFirstVisible(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes)
{
if (node.IsVisible)
return node;
TreeNode first = FindFirstVisible(node.Nodes);
if (first != null)
return first;
}
return null;
}
Для вызова используйте следующие функции:
TreeNode first = FindFirstVisible(tree.Nodes);
Для полноты картины вы также можете проверить (что немного отличается от того, что вы просите):
TreeView элемент.Свойство TopNode (System.Окна.Формы) | Microsoft Docs[
^]
На самом деле, подумав немного дольше, вам даже не нужно будет копаться в дереве. Я считаю, что для того, чтобы дочерний узел был виден, должен быть виден и родитель. Итак, я думаю, что у вас либо должен быть видимый узел верхнего уровня, либо никаких узлов не видно. Итак, должно сработать следующее:
private static TreeNode FindFirstVisible(TreeNodeCollection nodes) =>
nodes.Cast<TreeNode>().FirstOrDefault(node => node.IsVisible);
Основываясь на последующей информации, и если вы беспокоитесь о прокрутке, следующие методы позволят вам выбрать последний частично или полностью видимый узел. С помощью
NextVisibleNode
не будем рассматривать, вышел ли узел из диапазона прокрутки.
private TreeNode GetFirstVisibleNode(TreeView tree, bool includePartial)
{
if (!includePartial)
return tree.TopNode;
Rectangle treeBounds = tree.ClientRectangle;
return tree.Nodes.Cast<TreeNode>()
.FirstOrDefault(node => node.IsVisible &&
treeBounds.Contains(node.Bounds));
}
private TreeNode GetLastVisibleNode(TreeView tree, bool includePartial)
{
TreeNode last = GetFirstVisibleNode(tree, includePartial);
Rectangle treeBounds = tree.Bounds;
for (TreeNode node = last; node != null; node = node.NextVisibleNode)
{
if (includePartial)
{
if (!treeBounds.IntersectsWith(node.Bounds))
break;
}
else
{
if (!treeBounds.Contains(node.Bounds))
break;
}
last = node;
}
return last;
}
[no name]
Во-первых: я случайно оценил ваш вопрос одной звездой :( мне очень жаль!
Второе: я нашел другое решение, которое работает очень хорошо, поэтому я не тестировал ваше
0x01AA
Вы можете легко исправить свой голос, нажав на 5-ю звезду :-)
Eric Lynch
Без проблем. Возможно, вы захотите прочитать ответ. Если вы ищете первый действительно видимый узел (IsVisible=true и не прокручивается вне поля зрения), то TreeView.TopNode-это лучший способ пойти. В противном случае не беспокойтесь о рекурсии, просто изучите узлы верхнего уровня, один из них гарантированно будет первым видимым узлом, если какие-либо узлы в дереве видны. Это простой фрагмент LINQ, представленный в конце моего решения. Кроме того, что касается голосования, я думаю, что вы можете отредактировать свой выбор...Я забыл. В любом случае, никаких проблем.
[no name]
Спасибо, что показали мне вид на дерево.Свойство TopNode! Я использовал это, чтобы добраться до первого, а затем в основном сделал то же самое, что и раньше (что вы можете видеть в моем вопросе) с немного другой семантикой.
Кроме того, теперь я мог редактировать свой голос (раньше не мог этого сделать, поэтому извинился). Я отмечу Ваш ответ как принятый, а также добавлю третий ответ с тем, что я сделал сейчас, который гораздо легче читать для меня, как новичка в C#.
Eric Lynch
Еще одна вещь, которую вы, возможно, захотите рассмотреть, узел может иметь IsVisible = true и все еще не быть видимым, потому что он прокручивается вне диапазона. К сожалению, NextVisibleNode не рассматривает прокрутку. Я обновил решение, включив в него методы, учитывающие прокрутку, на случай, если это входит в ваши требования.