一、查找xaml中命名注冊的元素
<Button x:Name="btn1" Content="顯示內容" HorizontalAlignment="Left" Margin="25,115,0,0" VerticalAlignment="Top" Width="80" Height="60" Click="btn1_Click"/> <TextBox x:Name="txtOne" HorizontalAlignment="Left" Height="23" Margin="25,62,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="80"/>
//使用FindName() 查找 TextBox txtOne = this.FindName("txtOne") as TextBox; if (txtOne != null) { MessageBox.Show(txtOne.Text); //可以訪問到 } TextBox txtTwo = btn1.FindName("txtOne") as TextBox; if (txtTwo != null) { MessageBox.Show(txtTwo.Text); //也可以訪問到 }
二、查找后台代碼命名注冊的元素
后台添加方式
TextBlock block = new TextBlock(); block.Text = "海上生明月"; panelOne.RegisterName("block1", block); //將block命名block1名稱注冊到panelOne上 panelOne.Children.Add(block);
//從當前窗口獲取,可以訪問到 TextBlock block1 = btn1.FindName("block1") as TextBlock; if (block1 != null) { MessageBox.Show(block1.Text); } //從Panel獲取,可以訪問到 TextBlock block2 = panelOne.FindName("block1") as TextBlock; if (block2 != null) { MessageBox.Show("panelOne:"+block2.Text); }
注釋:元素名稱Name注冊, 不能重復。
-----------以下內容轉載:http://www.cnblogs.com/Clingingboy/archive/2010/11/29/1891253.html
預設置元素名字
WPF有兩種方式設置元素的Name
<StackPanel x:Name="panel"> <Label Name="name1" Content="Name1Label"/> <Label x:Name="name2" Content="Name2Label"/> </StackPanel>
這里我們的重點不在於討論Name和x:Name的區別,
Name是真正元素上的屬性,x:Name而則xaml(語法解析)的魔力,我們所看到的只能是表象.
不僅僅是注冊元素的名字
除了Element之外,其他類型也是可以的,如
<Label> <Label.BorderBrush> <SolidColorBrush x:Name="brushName"></SolidColorBrush> </Label.BorderBrush> </Label>
有些基本類型在xaml中無法設置,如String,Int類型等.但可以通過代碼設置
this.RegisterName("str", "Hello");
這里只有功能示例而已,但實際中千萬別這么做,本身不為此設計.
查找UserControl的元素
先定義一個UserControl
<UserControl x:Class="NameScopeDemo.MyUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <Button HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="btn">UserControl Button</Button> </Grid> </UserControl>
在主窗體中使用UserControl
<StackPanel x:Name="panel"> <local:MyUserControl x:Name="myControl"></local:MyUserControl> </StackPanel>
現在查找結果如下
若使用主窗體去無法查找到btn的話,但通過UserControl就可以.
在設計上將UI切分了,但卻給查找元素造成了麻煩了。
命名范圍(NameScope)
若以Code方式,添加方式則如下
uc = new MyUserControl(); var ns = new NameScope(); this.RegisterName("myControl", uc); panel.Children.Add(uc);
為UserControl創建了一個獨立的命名范圍,想要查找MyUserControl的元素可以通過MyUserControl的級別的FindName來查找
模板取元素
<ContentControl x:Name="cc"> <ContentControl.ContentTemplate> <DataTemplate> <Button HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="btn">UserControl Button</Button> </DataTemplate> </ContentControl.ContentTemplate> </ContentControl>
看到上面代碼,cc無法通過FindName查找到btn,只有模板的根元素才可以,這個根元素一般是ContentPresenter,所以當在模板內查找元素時,必須告訴其根元素
public Object FindName( string name, FrameworkElement templatedParent )
那么首先我們就必須找到ContentPresenter,而只能通過視覺樹上面找,整體而言還是比較麻煩的,不知道為何內部API不封裝一下.
將模板內的元素名字注冊到父級
var ns = uc.GetValue(NameScope.NameScopeProperty) as IDictionary<string, object>; var localNS = this.GetValue(NameScope.NameScopeProperty) as IDictionary<string, object>; foreach (var n in ns) { if (localNS.ContainsKey(n.Key)) { this.RegisterName(n.Key, n.Value); } }
首先獲取當前元素的NameScope,然后再將其注冊到父級命名范圍內以方便查找,值得注意的是模板內部的有些Name是固定的,如ScrollBar,其內部模板元素Name命名是有規定的,所以不要將其注冊在內.