wpf 怎么获取Template中的控件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wpf 怎么获取Template中的控件相关的知识,希望对你有一定的参考价值。

我设置了window元素的style属性,里面编写了自己的模版但是,我该怎么获取到模版中的元素呢,求高手解答,我的程序代码如下:
xaml部分:style代码
<Style x:Key="BaseWindow" TargetType="Window">
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="Width" Value="800"/>
<Setter Property="Height" Value="600"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Border Margin="8" Background="White" Name="BorderWindow">
<Border.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" Color="#00666666"/>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid Background="Blue" Grid.Row="0">
<Button Name="BtnClose" Style="StaticResource BtnCloseStyle" ToolTip="关闭"/>
<Button x:Name="BtnMax" Style="StaticResource BtnMaxStyle"/>
<Button x:Name="BtnMin" Style="StaticResource BtnMinStyle"/>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
window标签里面设置style属性为“BaseWindow”,但在cs代码中怎么获取模版中的三个button呢

在ControlTemplate中找控件最重要的就是让控件初始化到visualtree上
给你个链接做参考
http://www.cnblogs.com/midcn/archive/2011/05/24/2055276.html
参考技术A findChildById(BtnClose),
然后你就可以用了。
但是这样写好傻。
参考技术B 亲,你弄出来了没怎么弄得

通过 WPF 中的 Uid 获取对象

【中文标题】通过 WPF 中的 Uid 获取对象【英文标题】:Get object by its Uid in WPF 【发布时间】:2010-12-25 15:33:44 【问题描述】:

我在 WPF 中有一个具有唯一 Uid 的控件。如何通过 Uid 检索对象?

【问题讨论】:

请详细说明。你的UID是什么?它是如何设置的? 它是 wpf 或 silverlight 中任何控件的依赖属性。我已经设法解决了这个问题,但我想知道是否存在内置方法。 【参考方案1】:

我对最佳答案的一个问题是它不会在内容控件(例如用户控件)内部查找其内容中的元素。为了在这些内部进行搜索,我扩展了函数以查看兼容控件的 Content 属性。

public static UIElement FindUid(this DependencyObject parent, string uid)

    var count = VisualTreeHelper.GetChildrenCount(parent);

    for (int i = 0; i < count; i++)
    
        var el = VisualTreeHelper.GetChild(parent, i) as UIElement;
        if (el == null) continue;

        if (el.Uid == uid) return el;

        el = el.FindUid(uid);
        if (el != null) return el;
    

    if (parent is ContentControl)
    
        UIElement content = (parent as ContentControl).Content as UIElement;
        if (content != null)
        
            if (content.Uid == uid) return content;

            var el = content.FindUid(uid);
            if (el != null) return el;
        
    
    return null;

【讨论】:

【参考方案2】:

这样更好。

public static UIElement FindUid(this DependencyObject parent, string uid) 
    int count = VisualTreeHelper.GetChildrenCount(parent);

    for (int i = 0; i < count; i++) 
        UIElement el = VisualTreeHelper.GetChild(parent, i) as UIElement;
        if (el != null) 
            if (el.Uid == uid)  return el; 
            el = el.FindUid(uid);
        
    
        return null;

【讨论】:

如果您的代码不起作用,那就再好不过了。你的递归被打破了。 el.FindUid(uid)的结果,如果不为null,必须返回。【参考方案3】:
public static UIElement GetByUid(DependencyObject rootElement, string uid)

    foreach (UIElement element in LogicalTreeHelper.GetChildren(rootElement).OfType<UIElement>())
    
        if (element.Uid == uid)
            return element;
        UIElement resultChildren = GetByUid(element, uid);
        if (resultChildren != null)
            return resultChildren;
    
    return null;

【讨论】:

【参考方案4】:

您几乎必须通过蛮力来做到这一点。这是您可以使用的辅助扩展方法:

private static UIElement FindUid(this DependencyObject parent, string uid)

    var count = VisualTreeHelper.GetChildrenCount(parent);
    if (count == 0) return null;

    for (int i = 0; i < count; i++)
    
        var el = VisualTreeHelper.GetChild(parent, i) as UIElement;
        if (el == null) continue;

        if (el.Uid == uid) return el;

        el = el.FindUid(uid);
        if (el != null) return el;
    
    return null;

那么你可以这样称呼它:

var el = FindUid("someUid");

【讨论】:

GetChild(parent, N) 的复杂度不是 O(N) 吗? foreach 方法对我来说似乎更清晰(更清晰)。 如msdn 所述,如果未设置AutomationId,WindowsAutomationFramework 将默认为Uid(如果已设置)或ControlName(如果已设置)(选中通过检查.exe)。所以在某些情况下,AutomationIds 的工具就足够了。

以上是关于wpf 怎么获取Template中的控件的主要内容,如果未能解决你的问题,请参考以下文章

wpf 怎么获取StackPanel 中控件的位置。

WPF前台xaml中的控件名在后台拿不到,后台代码中显示“当前上下文不存在名称‘xxx’”

WPF ComboBox控件的外观怎么修改

wpf 怎么获取一个控件的宽度?

WPF Template模版之寻找失落的控件

WPF QuickStart系列之样式和模板(Style and Template)