利用FindName找到容器中的控件

来源:互联网 发布:淘宝多少个好评一个钻 编辑:程序博客网 时间:2024/06/06 08:49

MSDN上FindName有这样一句话,如果元素具有子元素,这些子元素都按递归方式搜索请求的命名元素。所以,不管XAML中嵌套了多少层Grid,StackPane之类的,只要知道控件所在的一个容器以及要找的控件Name,就可以用FindName去找到控件,然后去操作。

XAML如下:

<Grid>        <StackPanel Name="stkpanel1">            <StackPanel Name="stkpanel2">            <TextBox Name="txtbox1" Width="50" Height="30" HorizontalAlignment="Left"/>            </StackPanel>            <StackPanel Name="stkpanel3">            <TextBox Name="txtbox2" Width="50" Height="30" HorizontalAlignment="Left"/>            <Button Name="btn" Content="Find" Click="btn1_Click" Height="30" Width="50" HorizontalAlignment="Left"/>            </StackPanel>        </StackPanel>                </Grid>

CS文件中很简单的一段:

private void btn1_Click(object sender, RoutedEventArgs e)        {            TextBox txtbox = (stkpanel1.FindName("txtbox2")) as TextBox;            txtbox.Text = "Gotcha";        }

结果就是这样:




上面是最简单的例子,下面是一个TreeView里面的用法。

 <Window.Resources>        <Style TargetType="TreeViewItem">            <Setter Property="IsExpanded" Value="True" />        </Style>    </Window.Resources>    <Grid>        <Grid.ColumnDefinitions>            <ColumnDefinition/>            <ColumnDefinition/>        </Grid.ColumnDefinitions>        <TreeView Name="TVCountry" Margin="3">            <TreeView.ItemTemplate>                <HierarchicalDataTemplate ItemsSource="{Binding Children}">                    <StackPanel Orientation="Horizontal">                        <CheckBox Name="chkbox"/>                        <TextBlock Name="txtblock" Text="{Binding Name}" MouseLeftButtonDown="txtblock_MouseLeftButtonDown" />                    </StackPanel>                </HierarchicalDataTemplate>            </TreeView.ItemTemplate>        </TreeView>        <StackPanel Grid.Column="1">            <TextBox Name="txtbox"/>        </StackPanel>    </Grid>
这个是XAML,最上面的Resources就是初始化的时候把树形控件的节点全部展开,不需要的话删掉就行。

 public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();        }        protected override void OnInitialized(EventArgs e)        {            base.OnInitialized(e);            this.Create();        }               public class TreeNode        {            public string Name { set; get; }            public int ID { set; get; }            public int ParentID { set; get; }            public List<TreeNode> Children { set; get; }        }        //加载数据        void Create()        {            List<TreeNode> listtmp = new List<TreeNode>();            List<TreeNode> list = new List<TreeNode>();            listtmp.Add(new TreeNode() { Name = "中国", ID = 101, ParentID = 0 , Children = new List<TreeNode>() });            listtmp.Add(new TreeNode() { Name = "江苏", ID = 102, ParentID = 101, Children = new List<TreeNode>() });            listtmp.Add(new TreeNode() { Name = "浙江", ID = 103, ParentID = 101, Children = new List<TreeNode>() });            listtmp.Add(new TreeNode() { Name = "南京", ID = 104, ParentID = 102, Children = new List<TreeNode>() });            listtmp.Add(new TreeNode() { Name = "苏州", ID = 105, ParentID = 102, Children = new List<TreeNode>() });            listtmp.Add(new TreeNode() { Name = "温州", ID = 106, ParentID = 103, Children = new List<TreeNode>() });            listtmp.Add(new TreeNode() { Name = "宁波", ID = 107, ParentID = 103, Children = new List<TreeNode>() });            listtmp.Add(new TreeNode() { Name = "美国", ID = 108, ParentID = 0, Children = new List<TreeNode>() });            listtmp.Add(new TreeNode() { Name = "加利福尼亚", ID = 109, ParentID = 108, Children = new List<TreeNode>() });            listtmp.Add(new TreeNode() { Name = "洛杉矶", ID = 110, ParentID = 109, Children = new List<TreeNode>() });            foreach (var item in listtmp)            {                if (item.ParentID == 0)                {                    list.Add(item);                }                foreach (var item1 in listtmp)                {                    if (item1.ParentID == item.ID)                    {                        item.Children.Add(item1);                        //item.Children = listtmp.Where(v => v != null && v.ParentID != null && v.ParentID == item.ID).ToList();                    }                }            }            this.TVCountry.ItemsSource = list;                   }        private void txtblock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)        {            TextBlock tb = sender as TextBlock;

   

   txtbox.Text = tb.Text;          StackPanel stk = (VisualTreeHelper.GetParent(tb)) as StackPanel;          CheckBox chk = (stk.FindName("chkbox")) as CheckBox;          chk.IsChecked = !chk.IsChecked;        }    }

(不知道上面为什么会有  <span style="white-space:pre">  </span>   删掉就行。

由于就是一个简单的例子,就直接在代码里给出了数据。

这里需要的效果是点击树形控件TextBlock部分的时候,CheckBox也会相应的变化,在右边的TextBox里显示出TextBlock里的文字。所以就通过TextBlock找到了它的上层容器StackPanel,然后通过FindName找到CheckBox,大功告成。

继续往下写,还可以将这个小程序更加完善一点。

但是这里的问题是,选中TextBlock以后可以改变CheckBox,但是点击CheckBox却不会选中相应的TreeViewItem。没关系,我们再往下加功能。

首先给CheckBox加一个事件,像这样

 <CheckBox Name="chkbox" Click="chkbox_Click" />
在上面的CS文件里加上下面一段

 private void chkbox_Click(object sender, RoutedEventArgs e)        {            CheckBox chkbox = sender as CheckBox;            StackPanel stk = (VisualTreeHelper.GetParent(chkbox)) as StackPanel;            TextBlock tb = (stk.FindName("txtblock")) as TextBlock;            txtbox.Text = tb.Text;            ContentPresenter tvi = (VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(chkbox))) as ContentPresenter;            if (tvi != null)            {                TreeNode node = tvi.DataContext as TreeNode;                TreeViewItem tvitem = FindTreeViewItemContainer(this.TVCountry, node);                tvitem.IsSelected = true;            }        }        //找到一个TreeNode所在的TreeViewItem        public TreeViewItem FindTreeViewItemContainer(ItemsControl root, object info)        {            if (root == null) { return null; }            TreeViewItem tvi = root.ItemContainerGenerator.ContainerFromItem(info) as TreeViewItem;            if (tvi == null)            {                if (root.Items != null)                {                    foreach (var item in root.Items)                    {                        tvi = FindTreeViewItemContainer(root.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem, info);                        if (tvi != null)                        {                            break;                        }                    }                }            }            return tvi;        }
这样就完整啦。具体的效果如下图:



刚接触WPF,作为自己的一点记录,做的东西很简单,希望能和一样刚入门的朋友一起交流。

原创粉丝点击