WPF:理解ContentControl——动态添加控件和查找控件

我认为WPF的核心改变之一就是控件模型发生了重要的变化,大的方面说,现在窗口中的控件(大部分)都没有独立的Hwnd了。而且控件可以通过所谓的模板提供各种各样的表现形式。

这一篇就来谈一谈ContentControl,的第一部分,动态添加控件和查找控件

什么是ContentControl呢?其实WPF的绝大部分的控件,还包括窗口本身都是继承自ContentControl的。

有的时候,我们需要在窗口出来之后,再动态添加一些控件。例如一个最简单的场景:我们需要做一个扫雷程序,该扫雷程序根据用户选择的难易程度决定要显示多少个地雷。

为了便于理解,大家可以看下面这三个图片

ok,我们还是回想一下在Windows Forms里面怎么做?

using System;
using System.Windows.Forms; namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
//初级版,实例化6*6一共64个按钮
CreateButton(6, 6);
} private void button2_Click(object sender, EventArgs e)
{
//高级版,实例化9*9一共81个按钮
CreateButton(9, 9);
} private void CreateButton(int x, int y) {
panel1.SuspendLayout();
panel1.Controls.Clear(); //四个方向的边距都是5
int width = (panel1.Width-(x+1)*5)/x;
int height = (panel1.Height-(y+1)*5)/y; for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
Button bt = new Button()
{
Width = width,
Height = height,
Left = i*width+5,
Top = j*height+5
}; panel1.Controls.Add(bt); }
} panel1.ResumeLayout();
} }
}

我们可以花一点点时间稍微解释一下,其实我们就是用循环的方式,动态地创建了一批按钮出来,然后将他们添加到Panel的Controls集合中去。

那么,同样的思路放在WPF中来是否可行呢?我们一步一步来看吧

首先,在WPF中进行布局控制有几个主要的容器

  • Canvas是按照绝对位置定位的,很像上面的Panel这种机制;
  • StackPanel呢,则是基于流模式的,它没有绝对定位的概念,一批控件要么从左到右排列,要么从上而下排列
  • Grid,可能是用的最多的,它可以提供按照行和列的方式更好地组织控件。而事实上,在Grid里面也可以嵌入Canvas和StackPanel,他们结合可以构造出足够复杂的 界面。

那么,我们就来尝试用Canvas实现与Windows Forms类似的效果吧

那么,我们的代码有什么区别呢?

第一部分是XAML代码

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="我的扫雷程序" Height="516" Width="592">
<Grid>
<Button Height="23" HorizontalAlignment="Left" Margin="20,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click">初级</Button>
<Button Height="23" HorizontalAlignment="Left" Margin="101,12,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click">高级</Button>
<Canvas Margin="20,41,12,12" Name="canvas1" />
</Grid>
</Window>

第二部分是C#代码

using System.Windows;
using System.Windows.Controls; namespace WpfApplication1
{
/// <summary>
/// Window1.xaml 的交互逻辑
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
} private void button1_Click(object sender, RoutedEventArgs e)
{
CreateButton(6, 6);
} private void button2_Click(object sender, RoutedEventArgs e)
{
CreateButton(9, 9);
} private void CreateButton(int x, int y)
{ canvas1.Children.Clear(); //四个方向的边距都是5
double width = (this.canvas1.ActualWidth - (x + 1) * 5) / x;
double height = (this.canvas1.ActualHeight - (y + 1) * 5) / y; for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
Button bt = new Button()
{
Width = width,
Height = height
}; Canvas.SetTop(bt, j * height + 5);
Canvas.SetLeft(bt, i * width + 5);
//这两句很关键。按钮在Canvas中的定位与它自己的Left以及Top不是一个概念 canvas1.Children.Add(bt); }
} } }
}

我们发现了以下区别

1. 现在没有Controls这个概念了,而是有一个Children属性,代表了所有的子内容

2.针对不同的容器,有一些特殊的方法来定位子元素。例如Canvas的SetTop等方法 。

WPF:理解ContentControl——动态添加控件和查找控件的更多相关文章

  1. c#winform如何通过控件名查找控件

    //根据控件名称查找控件 //作用根据控件的配置项目, Control[] myfindcs = this.Controls.Find("button4", true); if ( ...

  2. 老李推荐:第14章9节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-遍历控件树查找控件

    老李推荐:第14章9节<MonkeyRunner源码剖析> HierarchyViewer实现原理-遍历控件树查找控件   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员 ...

  3. ASP.NET给Table动态添加删除行,并且得到控件的值

    ASP.NET给Table动态添加控件并且得到控件的值 由于跟老师做一个小的项目,可是我自己又不太懂js,所以一直为动态建立表格并且能动态的取值和赋值感到苦恼.起初在网上找到了一些js资源,解决了动态 ...

  4. 如何给动态添加的form表单控件添加表单验证

    最近使用jQuery Validate做表单验证很方便,api地址为http://www.runoob.com/jquery/jquery-plugin-validate.html 但是在使用的时候也 ...

  5. asp.net 动态添加多个用户控件

    动态添加多个相同用户控件,并使每个用户控件获取不同的内容. 用户控件代码: 代码WebControls using System; using System.Collections.Generic;  ...

  6. WPF 动态添加控件以及样式字典的引用(Style introduction)

    原文:WPF 动态添加控件以及样式字典的引用(Style introduction) 我们想要达到的结果是,绑定多个Checkbox然后我们还可以获取它是否被选中,其实很简单,我们只要找到那几个关键的 ...

  7. WPF中TreeView控件数据绑定和后台动态添加数据(一)

    数据绑定: 更新内容:补充在MVVM模式上的TreeView控件数据绑定的代码. xaml代码: <TreeView Name="syntaxTree" ItemsSourc ...

  8. C# WPF后台动态添加控件(经典)

    概述 在Winform中从后台添加控件相对比较容易,但是在WPF中,我们知道界面是通过XAML编写的,如何把后台写好的控件动态添加到前台呢?本节举例介绍这个问题. 这里要用到UniformGrid布局 ...

  9. Android 在布局容器中动态添加控件

    这里,通过一个小demo,就可以掌握在布局容器中动态添加控件,以动态添加Button控件为例,添加其他控件同样道理. 1.addView 添加控件到布局容器 2.removeView 在布局容器中删掉 ...

随机推荐

  1. CentOS 7命令行安装GNOME、KDE图形界面

    https://www.linuxidc.com/Linux/2018-04/152000.htm

  2. [ZJOI2010]贪吃的老鼠

    很不错的一道网络流的题目 二分答案是显然的 首先不考虑每个饼干只能一个老鼠吃 那很显然的建图就是将时间点按照开始结束的点分成2*n-1段 然后对每一段时间建m个老鼠的点,然后s-它限流,再从它到目前可 ...

  3. asp.net core 内置DI容器的一点小理解

    DI容器本质上是一个工厂,负责提供向它请求的类型的实例. .net core内置了一个轻量级的DI容器,方便开发人员面向接口编程和依赖倒置(IOC). 具体体现为Micorosoft.Extensio ...

  4. asp.net core web项目目录解读

    Connected Services 和传统.net web项目相比,它的功能类似于添加webservice或者wcf service的引用.暂时用不到,有兴趣的小伙伴可以深入了解.右键这个目录可以看 ...

  5. BZOJ1878 [SDOI2009]HH的项链 树状数组 或 莫队

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1878 题意概括 给出一个长度为n的序列,用m次询问,问区间Li~Ri中有多少种不同的数. 0< ...

  6. 6-3 矩阵链成 uva 442

    较为简单的栈题 思路比较好 一次ac 1.char word :word=A:直接  a[word]=xxxx,不用 a[‘word’]=xxxx #include<bits/stdc++.h& ...

  7. 如何在Maven官网下载历史版本

    如何在Maven官网下载历史版本 历史版本一般会隔一段时间,便找不到,官网会及时显示的是最新版本.不多说,直接进入. https://archive.apache.org/dist/maven/bin ...

  8. Linux虚拟机上安装redis

    1.检查安装依赖程序 yum install gcc-c++ yum install -y tcl yum install wget 2.获取安装文件 wget http://download.red ...

  9. win7查看其它工作组 win7 所有工作组

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha win7 所有工作组 ==== win7  网络 工作组 查找 自身有问题.  多刷新几 ...

  10. BZOJ.2177.曼哈顿最小生成树(Kruskal)

    \(Solution\) 参考 对于每个点,向唯一有可能与它形成MST的8个点连边,由于是双向单边,所以每个点最多连出4条边(证明见blog) 怎么找到一个区域内最近的点? 只考虑y轴右侧45°的区域 ...