我需要在WPF控件层次结构中搜索与给定名称或类型匹配的控件。我该怎么做呢?
当前回答
您还可以使用FrameworkElement.FindName(string)按名称查找元素。
考虑到:
<UserControl ...>
<TextBlock x:Name="myTextBlock" />
</UserControl>
在代码隐藏文件中,你可以这样写:
var myTextBlock = (TextBlock)this.FindName("myTextBlock");
当然,因为它是使用x:Name定义的,所以您可以只引用生成的字段,但是您可能希望动态而不是静态地查找它。
这种方法也可用于模板,其中命名项出现多次(每次使用模板一次)。
其他回答
您可以使用VisualTreeHelper来查找控件。下面是一个使用VisualTreeHelper查找指定类型的父控件的方法。您也可以使用VisualTreeHelper以其他方式查找控件。
public static class UIHelper
{
/// <summary>
/// Finds a parent of a given item on the visual tree.
/// </summary>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="child">A direct or indirect child of the queried item.</param>
/// <returns>The first parent item that matches the submitted type parameter.
/// If not matching item can be found, a null reference is being returned.</returns>
public static T FindVisualParent<T>(DependencyObject child)
where T : DependencyObject
{
// get parent item
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
// we’ve reached the end of the tree
if (parentObject == null) return null;
// check if the parent matches the type we’re looking for
T parent = parentObject as T;
if (parent != null)
{
return parent;
}
else
{
// use recursion to proceed with next level
return FindVisualParent<T>(parentObject);
}
}
}
这样叫它:
Window owner = UIHelper.FindVisualParent<Window>(myControl);
要从代码中找到给定类型的祖先,您可以使用:
[CanBeNull]
public static T FindAncestor<T>(DependencyObject d) where T : DependencyObject
{
while (true)
{
d = VisualTreeHelper.GetParent(d);
if (d == null)
return null;
var t = d as T;
if (t != null)
return t;
}
}
这个实现使用迭代而不是递归,可以稍微快一点。
如果你使用的是c# 7,这段代码可以略短:
[CanBeNull]
public static T FindAncestor<T>(DependencyObject d) where T : DependencyObject
{
while (true)
{
d = VisualTreeHelper.GetParent(d);
if (d == null)
return null;
if (d is T t)
return t;
}
}
试试这个
<TextBlock x:Name="txtblock" FontSize="24" >Hai Welcom to this page
</TextBlock>
后面的代码
var txtblock = sender as Textblock;
txtblock.Foreground = "Red"
这些选项已经讨论了如何在c#中遍历可视化树。 使用RelativeSource标记扩展也可以遍历xaml中的可视树。msdn
按类型查找
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type <TypeToFind>}}}"
这将消除一些元素-您应该像这样扩展它,以支持更广泛的控件数组。简单的讨论,请看这里
/// <summary>
/// Helper methods for UI-related tasks.
/// </summary>
public static class UIHelper
{
/// <summary>
/// Finds a parent of a given item on the visual tree.
/// </summary>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="child">A direct or indirect child of the
/// queried item.</param>
/// <returns>The first parent item that matches the submitted
/// type parameter. If not matching item can be found, a null
/// reference is being returned.</returns>
public static T TryFindParent<T>(DependencyObject child)
where T : DependencyObject
{
//get parent item
DependencyObject parentObject = GetParentObject(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
{
return parent;
}
else
{
//use recursion to proceed with next level
return TryFindParent<T>(parentObject);
}
}
/// <summary>
/// This method is an alternative to WPF's
/// <see cref="VisualTreeHelper.GetParent"/> method, which also
/// supports content elements. Do note, that for content element,
/// this method falls back to the logical tree of the element!
/// </summary>
/// <param name="child">The item to be processed.</param>
/// <returns>The submitted item's parent, if available. Otherwise
/// null.</returns>
public static DependencyObject GetParentObject(DependencyObject child)
{
if (child == null) return null;
ContentElement contentElement = child as ContentElement;
if (contentElement != null)
{
DependencyObject parent = ContentOperations.GetParent(contentElement);
if (parent != null) return parent;
FrameworkContentElement fce = contentElement as FrameworkContentElement;
return fce != null ? fce.Parent : null;
}
//if it's not a ContentElement, rely on VisualTreeHelper
return VisualTreeHelper.GetParent(child);
}
}
推荐文章
- 在窗口上设置设计时间DataContext是一个编译器错误?
- 调用线程必须是STA,因为许多UI组件都要求这一点
- ContentControl和ContentPresenter有什么区别?
- WPF中控制模板和数据模板的区别
- 如何隐藏关闭按钮在WPF窗口?
- UI线程上的任务继续
- 我怎么能得到'查找'忽略。svn目录?
- WPF数据绑定:我如何访问“父”数据上下文?
- 从System.Drawing.Bitmap中加载WPF BitmapImage
- 我应该使用什么MVVM框架?
- 在WPF中引入一个窗口到前面
- Visual Studio单击“查找结果”在错误的窗口中打开代码
- 窗口高度=“自动”未按预期工作
- 我如何得到一个动画gif在WPF工作?
- ListBox和ListView的区别是什么