欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C# WPF 父控件通過使用可視化樹找到子控件的示例代碼

 更新時間:2018年08月24日 11:27:10   作者:hello黃先森  
這篇文章主要介紹了C# WPF 父控件通過使用可視化樹找到子控件的示例代碼,需要的朋友可以參考下

在我們使用WPF設(shè)計前臺界面時,經(jīng)常會重寫數(shù)據(jù)模板,或者把控件放到數(shù)據(jù)模板里。但是一旦將控件放到數(shù)據(jù)模板中,在后臺就沒有辦法通過控件的名字來獲取它了,更沒辦法對它進行操作(例如,隱藏,改變控件的某個值)。

如果你是比我還白的小白,對我剛剛陳述的東西不清楚,接下來我簡單說一下什么是把控件放在數(shù)據(jù)模板中,怎么樣的情況沒法后臺通過名字來獲取控件,如果讀者對于數(shù)據(jù)模板這些事兒已經(jīng)清楚了,或者只關(guān)心如何使用可視化樹可以將這部分跳過哈。

先上代碼介紹一下什么是數(shù)據(jù)模板以WPF中ListBox控件為例:

<ListBox Name="ListBox_1" HorizontalAlignment="Left" Height="299" Margin="10,10,0,0" VerticalAlignment="Top" Width="497" MouseDoubleClick="ListBox_1_OnMouseDoubleClick">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <Button Name="Button_1" Content="666"></Button>
      </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

我在后臺設(shè)置了顯示了8行item,效果如下:

我們可以看到重寫數(shù)據(jù)模板實現(xiàn)的效果是在ListBox的每一項Item都是一個Button,這里介紹的只是一些簡單應用例子,重寫模板是很強大的。因為如果用到可視化樹多半是因為使用了數(shù)據(jù)模板在后臺用名字無法找到相應控件了,所以在此簡單介紹一下,方便理解。

接下來我們在后臺嘗試通過控件的名字來找到我們的ListBox和Button

我們發(fā)現(xiàn)通過控件的名字可以找到ListBox但是通過button的名字卻無法找到button,這就是數(shù)據(jù)模板搞的鬼。

但是沒有關(guān)系,我們可以通過可視化樹從ListBox里找到它的子控件我們想要的這個Button。

重點來了,先上代碼,可視化樹通過父控件找到它的子控件:

List<T> FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
    {
      try
      {
        List<T> list = new List<T>();
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
          DependencyObject child = VisualTreeHelper.GetChild(obj, i);
          if (child is T)
          {
            list.Add((T)child);
            List<T> childOfChildren = FindVisualChild<T>(child);
            if (childOfChildren != null)
            {
              list.AddRange(childOfChildren);
            }
          }
          else
          {
            List<T> childOfChildren = FindVisualChild<T>(child);
            if (childOfChildren != null)
            {
              list.AddRange(childOfChildren);
            }
          }
        }
        return list;
      }
      catch (Exception)
      {
        //MessageBox.Show(ee.Message);
        return null;
      }
    }

先將上面的方法復制到你的項目當中,此時對于可視化樹的應用已經(jīng)完成一半了。

接下來上代碼,通過可視化樹雙擊ListBox的ltem把對應的button的Content值從666改成777:

private void ListBox_1_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
      ListBoxItem myListBoxItem = (ListBoxItem)ListBox_1.ItemContainerGenerator.ContainerFromItem(ListBox_1.SelectedItem);
      List<Button> btnList = FindVisualChild<Button>(myListBoxItem);
      foreach (var item in btnList)
      {
        item.Content = "777";
      }
    }

效果就是雙擊哪個item哪個item中的button從666變成了777。

我們通過父控件找到了里面的子控件button,我們便可以對它進行任何操作(和用名字找到是一樣的)。

以上關(guān)于可視化樹的代碼可以應用于ListBox,DataGrid,ListView,TreeView,對于“.ItemContainerGenerator.ContainerFromItem”這段代碼的含義我暫時不是很理解,歡迎指教和交流。

通過以上的例子相信讀者已經(jīng)可以使用可視化樹找到相應的控件了,但在我的開發(fā)過程中曾遇到過一些問題,和對于使用可視化樹的一點小建議。

1.如果你在使用可視化樹執(zhí)行“ListBoxItem myListBoxItem = (ListBoxItem)ListBox_1.ItemContainerGenerator.ContainerFromItem(ListBox_1.SelectedItem);”這句返回值是空(實際上不是空),可能是因為界面沒有初始化完畢,我的理解是,在前臺這個控件還沒生成完畢,或者是你修改了值但前臺還沒有修改,可以加上這句:

控件名.UpdateLayout();

之后在使用可視化樹,這一條的說法和形容可能有點不嚴謹,歡迎指正交流。

2.可視化樹使用的是遞歸的方法,所以它的效率不是很高,如果在程序中大量使用可視化樹,會使得程序變慢的。

3.調(diào)用可視化樹返回的列表如果沒有找到相應的控件或是異常便會返回空值,所以建議在你遍歷可視化樹返回的列表時,請先判斷否非為空。

補充:WPF查找子控件和父控件方法

一、查找某種類型的子控件,并返回一個List集合
public List<T> GetChildObjects<T>(DependencyObject obj, Type typename) where T : FrameworkElement
{
DependencyObject child = null;
List<T> childList = new List<T>();
for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
{
child = VisualTreeHelper.GetChild(obj, i);
if (child is T && (((T)child).GetType() == typename))
{
childList.Add((T)child);
}
childList.AddRange(GetChildObjects<T>(child,typename));
}
return childList;
}
調(diào)用:
List<Button> listButtons = GetChildObjects<Button>(parentPanel, typeof(Button)); //parentPanel就是xaml里定義的控件的x:name
二、通過名稱查找子控件,并返回一個List集合
public List<T> GetChildObjects<T>(DependencyObject obj, string name) where T : FrameworkElement
{
DependencyObject child = null;
List<T> childList = new List<T>();
for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
{
child = VisualTreeHelper.GetChild(obj, i);
if (child is T && (((T)child).GetType() == name |string.IsNullOrEmpty(name)))
{
childList.Add((T)child);
}
childList.AddRange(GetChildObjects<T>(child,name));
}
return childList;
}
調(diào)用:
List<Button> listButtons = GetChildObjects<Button>(parentPanel, "button1");
三、通過名稱查找某子控件:
public T GetChildObject<T>(DependencyObject obj, string name) where T : FrameworkElement
{
DependencyObject child = null;
T grandChild = null;
for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
{
child = VisualTreeHelper.GetChild(obj, i);
if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
{
return (T)child;
}
else
{
grandChild = GetChildObject<T>(child, name);
if (grandChild != null)
return grandChild;
}
}
returnnull;
}
調(diào)用:
StackPanel sp = GetChildObject<StackPanel>(this.LayoutRoot, "spDemoPanel");
四、通過名稱查找父控件
public T GetParentObject<T>(DependencyObject obj, string name) where T : FrameworkElement
{
DependencyObject parent = VisualTreeHelper.GetParent(obj);
while (parent != null)
{
if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name)))
{
return (T)parent;
}
parent = VisualTreeHelper.GetParent(parent);
}
returnnull;
}
調(diào)用:
Grid layoutGrid = VTHelper.GetParentObject<Grid>(this.spDemoPanel, "LayoutRoot");

總結(jié)

以上所述是小編給大家介紹的C# WPF 父控件通過使用可視化樹找到子控件,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 詳解c# 泛型類的功能

    詳解c# 泛型類的功能

    這篇文章主要介紹了c# 泛型類的功能,幫助大家更好的理解和學習c#,感興趣的朋友可以了解下
    2020-10-10
  • c# 繼承快速入門

    c# 繼承快速入門

    這篇文章主要介紹了c# 繼承快速入門的相關(guān)資料,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下
    2021-03-03
  • C# 設(shè)計模式系列教程-建造者模式

    C# 設(shè)計模式系列教程-建造者模式

    用戶只需要指定要建造的類型就可以得到它們,而具體的建造過程和細節(jié)不需要知道。
    2016-06-06
  • c# 如何實現(xiàn)自動更新程序

    c# 如何實現(xiàn)自動更新程序

    這篇文章主要介紹了如何用c# 自動更新程序,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下
    2021-03-03
  • c#學習教程之JSON文件及解析實例

    c#學習教程之JSON文件及解析實例

    json作為互聯(lián)網(wǎng)上輕量便捷的數(shù)據(jù)傳輸格式,越來越受到重視,下面這篇文章主要給大家介紹了關(guān)于c#學習教程之JSON文件及解析的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • C#實現(xiàn)appSettings節(jié)點讀取與修改的方法

    C#實現(xiàn)appSettings節(jié)點讀取與修改的方法

    這篇文章主要介紹了C#實現(xiàn)appSettings節(jié)點讀取與修改的方法,是非常實用的技巧,需要的朋友可以參考下
    2014-10-10
  • C#的自定義語法糖的使用詳解

    C#的自定義語法糖的使用詳解

    這篇文章主要介紹了C#的自定義語法糖的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • 輸出的文本實現(xiàn)對齊的方法(超簡單)

    輸出的文本實現(xiàn)對齊的方法(超簡單)

    下面小編就為大家分享一篇c#輸出的文本實現(xiàn)對齊的方法,特別簡單!希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • C#畫筆Pen繪制曲線的方法

    C#畫筆Pen繪制曲線的方法

    這篇文章主要介紹了C#畫筆Pen繪制曲線的方法,主要涉及C#畫筆中DrawCurve方法的使用技巧,需要的朋友可以參考下
    2015-06-06
  • C#下載網(wǎng)頁并在控制臺輸出的方法

    C#下載網(wǎng)頁并在控制臺輸出的方法

    這篇文章主要介紹了C#下載網(wǎng)頁并在控制臺輸出的方法,涉及C#基于http協(xié)議進行網(wǎng)頁抓取及控制臺輸出顯示的相關(guān)技巧,需要的朋友可以參考下
    2015-07-07

最新評論