Arc*_*ger 41 c# wpf wpf-controls
我怎样才能类型的子控件ComboBox中MyContainer Grid的WPF?
<Grid x:Name="MyContainer">
<Label Content="Name" Name="label1" />
<Label Content="State" Name="label2" />
<ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox1"/>
<ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox3" />
<ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox4" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
这行给了我一个错误:
var myCombobox = this.MyContainer.Children.GetType(ComboBox);
Run Code Online (Sandbox Code Playgroud)
Mat*_*ton 76
此扩展方法将递归搜索所需类型的子元素:
public static T GetChildOfType<T>(this DependencyObject depObj)
where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child);
if (result != null) return result;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
所以使用它你可以要求MyContainer.GetChildOfType<ComboBox>().
Bot*_*000 38
儿童是UIElements的集合.因此,您需要迭代项目并确定每个项目是否属于所需类型.幸运的是,已经有一个Linq方法就是这样,即Enumerable.OfType<T>可以使用Extension Method语法方便地调用它:
var comboBoxes = this.MyContainer.Children.OfType<ComboBox>();
Run Code Online (Sandbox Code Playgroud)
此方法根据类型过滤集合,并在您的情况下仅返回类型的元素ComboBox.
如果您只想要第一个ComboBox(如您的变量名可能建议的那样),您只需追加FirstOrDefault()对查询的调用:
var myComboBox = this.MyContainer.Children.OfType<ComboBox>().FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
所有这些答案,但一个使用递归,IMO只是蹩脚的:)
获得视觉儿童:
public static IEnumerable<T> FindVisualChildren<T>([NotNull] this DependencyObject parent) where T : DependencyObject
{
if (parent == null)
throw new ArgumentNullException(nameof(parent));
var queue = new Queue<DependencyObject>(new[] {parent});
while (queue.Any())
{
var reference = queue.Dequeue();
var count = VisualTreeHelper.GetChildrenCount(reference);
for (var i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(reference, i);
if (child is T children)
yield return children;
queue.Enqueue(child);
}
}
}
Run Code Online (Sandbox Code Playgroud)
获取逻辑孩子:
public static IEnumerable<T> FindLogicalChildren<T>([NotNull] this DependencyObject parent) where T : DependencyObject
{
if (parent == null)
throw new ArgumentNullException(nameof(parent));
var queue = new Queue<DependencyObject>(new[] {parent});
while (queue.Any())
{
var reference = queue.Dequeue();
var children = LogicalTreeHelper.GetChildren(reference);
var objects = children.OfType<DependencyObject>();
foreach (var o in objects)
{
if (o is T child)
yield return child;
queue.Enqueue(o);
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这两个深度遍历树,如果您希望在第一次遇到时停止,则更改两个代码以将调用包含queue.Enqueue在一个else块中。