WPF Framework​Element.​Find​Name 根据名字查找控件

运行环境:Window7 64bit,NetFramework4.7,C# 7.0, 编者:乌龙哈里 2017-10-04


参考:

章节:


正文:

最近写个小玩意,本来是想用 TabControl 标明标签,然后 TabItem 做容器里面放些控件,但是我 TabItem里面的控件完全一样,用 TabItem 来做容器似乎太笨重了,于是想用个 StackPanel 来放标签,其他控件用个 Grid 来包裹就成了。测试的时候发现 FindName() 找不到后台程序生成的 RadioButton。程序如下:

Xaml 界面程序

<Window x:Class="学习FindName.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="6*"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="32"/>
        </Grid.RowDefinitions>
        <ListBox Name="lstShow" Grid.Row="0"/>
        <StackPanel Name="stackpanel" Orientation="Horizontal" Grid.Row="1"/>
        <Grid Grid.Row="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
            </Grid.ColumnDefinitions>
            <Button Name="btnAdd" Content="添加" Margin="3" Grid.Column="0" Click="btnAdd_Click" />
            <Button Name="btnDrop" Content="删除" Margin="3" Grid.Column="1" Click="btnDrop_Click" />
        </Grid>
    </Grid>
</Window>

C# 后台程序:

using System.Windows;
using System.Windows.Controls;

namespace 学习FindName
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private int RadioButtonNum = 0;

public MainWindow()
        {
            InitializeComponent();
        }
        //---添加 radiobutton
        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            RadioButtonNum++;
            string s = "rbn" + RadioButtonNum.ToString();
            RadioButton rbn = new RadioButton{ Name = s, Content = s,Margin=new Thickness(3)};
            rbn.Click += RadioButton_Click;
            stackpanel.Children.Add(rbn);
        }
        //---删除 radiobutton
        private void btnDrop_Click(object sender, RoutedEventArgs e)
        {
            string s = "rbn" + RadioButtonNum.ToString();
            RadioButton rbn = stackpanel.FindName(s) as RadioButton;
            stackpanel.Children.Remove(rbn);
        }
        private void RadioButton_Click(object sender, RoutedEventArgs e)
        {
            //(sender as RadioButton).IsChecked = true;
            string s = (sender as RadioButton).Name;
            RadioButtonNum = int.Parse(s[s.Length - 1].ToString());
            lstShow.Items.Add(s);
        }
    }
}

运行效果如下:

Framework​Element.​Find​Name 根据名字查找控件-LMLPHP

但是删除的时候,发现 FindName() 返回的值为 null,没有找到控件。找了半天资料,才发现不在前台 Xaml 里面定义的控件名字,要用 ​Register​Name() 方式来注册一下名字,后面的 FindName() 才能找到。
更改程序如下:

//---添加 radiobutton
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
    RadioButtonNum++;
    string s = "rbn" + RadioButtonNum.ToString();
    RadioButton rbn = new RadioButton{ Name = s, Content = s,Margin=new Thickness(3)};
    rbn.Click += RadioButton_Click;
    stackpanel.Children.Add(rbn);
    //注册一下名字,没有这句后面的 FindName() 将找不到控件
    stackpanel.RegisterName(s, rbn);
}
//---删除 radiobutton
private void btnDrop_Click(object sender, RoutedEventArgs e)
{
    string s = "rbn" + RadioButtonNum.ToString();

RadioButton rbn = stackpanel.FindName(s) as RadioButton;
    rbn.Click -= RadioButton_Click;//事件如果不注销,容易引起内存泄漏
    stackpanel.Children.Remove(rbn);
}
private void RadioButton_Click(object sender, RoutedEventArgs e)
{
    //(sender as RadioButton).IsChecked = true;
    string s = (sender as RadioButton).Name;
    RadioButtonNum = int.Parse(s[s.Length - 1].ToString());
    lstShow.Items.Add(s);
}

运行效果如下:

Framework​Element.​Find​Name 根据名字查找控件-LMLPHP

05-07 15:57