Window에서 모든 컨트롤을 유형별로 찾는 방법을 찾고 있습니다.
예를 들어 : 모두 찾기 TextBoxes
, 특정 인터페이스를 구현하는 모든 컨트롤 찾기 등
답변
이 트릭을해야합니다
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
그런 다음 컨트롤을 열거합니다.
foreach (TextBlock tb in FindVisualChildren<TextBlock>(window))
{
// do something with tb here
}
답변
가장 쉬운 방법입니다.
IEnumerable<myType> collection = control.Children.OfType<myType>();
여기서 control은 창의 루트 요소입니다.
답변
@Bryce Kahle의 답변을 @Mathias Lykkegaard Lorenzen의 제안과 사용에 따라 조정했습니다 LogicalTreeHelper
.
잘 작동하는 것 같습니다. 😉
public static IEnumerable<T> FindLogicalChildren<T> ( DependencyObject depObj ) where T : DependencyObject
{
if( depObj != null )
{
foreach( object rawChild in LogicalTreeHelper.GetChildren( depObj ) )
{
if( rawChild is DependencyObject )
{
DependencyObject child = (DependencyObject)rawChild;
if( child is T )
{
yield return (T)child;
}
foreach( T childOfChild in FindLogicalChildren<T>( child ) )
{
yield return childOfChild;
}
}
}
}
}
(여전히 @Benjamin Berry & @David R에서 언급 한대로 GroupBox 내부의 탭 컨트롤 또는 그리드를 확인하지 않습니다.) (또한 @noonand의 제안을 따르고 중복 자식을 제거했습니다! = null)
답변
헬퍼 클래스를 사용 VisualTreeHelper
하거나 관심 LogicalTreeHelper
있는 트리 에 따라 다를 수 있습니다. 둘 다 요소의 하위를 가져 오는 메소드를 제공합니다 (구문이 약간 다르지만). 필자는 종종 이러한 클래스를 사용하여 특정 유형의 첫 번째 항목을 찾았지만 해당 유형의 모든 객체를 찾도록 쉽게 수정할 수 있습니다.
public static DependencyObject FindInVisualTreeDown(DependencyObject obj, Type type)
{
if (obj != null)
{
if (obj.GetType() == type)
{
return obj;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject childReturn = FindInVisualTreeDown(VisualTreeHelper.GetChild(obj, i), type);
if (childReturn != null)
{
return childReturn;
}
}
}
return null;
}
답변
VisualTreeHelper.GetChildrenCount(depObj);
위의 여러 예제에서 사용 된 행 은 GroupBox
es에 대해 0이 아닌 카운트를 반환하지 않는 것으로 나타났습니다 . 특히 GroupBox
contains 포함 Grid
및 Grid
contains 하위 요소가 있습니다. 나는 이것이 GroupBox
둘 이상의 자녀를 포함 할 수 없기 때문에 이것이 가능하다고 생각 하며, 이것은 그 Content
재산에 저장됩니다 . GroupBox.Children
속성 유형 이 없습니다 . 이 작업을 매우 효율적으로 수행하지는 않았지만이 체인에서 첫 번째 “FindVisualChildren”예제를 다음과 같이 수정했습니다.
public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
int depObjCount = VisualTreeHelper.GetChildrenCount(depObj);
for (int i = 0; i <depObjCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
if (child is GroupBox)
{
GroupBox gb = child as GroupBox;
Object gpchild = gb.Content;
if (gpchild is T)
{
yield return (T)child;
child = gpchild as T;
}
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
답변
특정 유형의 모든 자식 목록을 얻으려면 다음을 사용할 수 있습니다.
private static IEnumerable<DependencyObject> FindInVisualTreeDown(DependencyObject obj, Type type)
{
if (obj != null)
{
if (obj.GetType() == type)
{
yield return obj;
}
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
foreach (var child in FindInVisualTreeDown(VisualTreeHelper.GetChild(obj, i), type))
{
if (child != null)
{
yield return child;
}
}
}
}
yield break;
}
답변
예를 들어 탭 컨트롤의 자식 탭 컨트롤을 찾을 수 있도록 재귀를 약간 변경합니다.
public static DependencyObject FindInVisualTreeDown(DependencyObject obj, Type type)
{
if (obj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child.GetType() == type)
{
return child;
}
DependencyObject childReturn = FindInVisualTreeDown(child, type);
if (childReturn != null)
{
return childReturn;
}
}
}
return null;
}