日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

WPF 元素的查找

發布時間:2025/4/5 asp.net 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WPF 元素的查找 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

javascript查找元素

在CSS選擇器出現之前我想下面兩行代碼是web開發人員最為熟悉的

document.getElementById(""); document.getElementsByName("");

html整個頁面的Id和Name是必須唯一的,并沒有局部Id和Name的概念,其實只要做到規范,就很少會出現Name重復等問題。

ASP.NET的Id

ASP.NET控件是有命名范圍的概念的,如一個UserControl,其Id會一直拉長,以導致寫js的時候異常麻煩.
下面介紹WPF的NameScope

預設置元素名字

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(語法解析)的魔力,我們所看到的只能是表象.

查找已設置Name的元素

WPF的基類元素FrameworkElement提供了FindName方法以提供查找設定的元素

以Code的形式添加元素

var label = new Label(); label.Name = "label3"; panel.Children.Add(label);

注意已經設置了Name

添加好以后,然后查找這個元素,會發現并不能查找到這個元素

上面就說過xaml是有魔力的,并非設置一個Name屬性就可以了的,其內部還有了一個叫RegisterName的方法,以注冊元素的Name(想象一下,如果有1000個樹節點,從根節點開始找最內部的節點那得多慢),有了Name就跟元素綁到一起了.
現修改如下,用RegisterName方法注冊(注意:即使注釋了Name 屬性也不會有影響)

var label = new Label(); // label.Name = "label3";this.RegisterName("label3", label);panel.Children.Add(label);

現在查找恢復成功


但會發現查找出來的元素Name還是空的.這就會造成歧義,建議應該Name屬性和RegisterName方法一起設置,

不僅僅是注冊元素的名字

除了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命名是有規定的,所以不要將其注冊在內.

下篇將繼續討論NameScope,綁定,視覺樹,邏輯樹之間的關系

總結

以上是生活随笔為你收集整理的WPF 元素的查找的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。