WPF:理解ContentControl——动态添加控件和查找控件
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——动态添加控件和查找控件的更多相关文章
- c#winform如何通过控件名查找控件
//根据控件名称查找控件 //作用根据控件的配置项目, Control[] myfindcs = this.Controls.Find("button4", true); if ( ...
- 老李推荐:第14章9节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-遍历控件树查找控件
老李推荐:第14章9节<MonkeyRunner源码剖析> HierarchyViewer实现原理-遍历控件树查找控件 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员 ...
- ASP.NET给Table动态添加删除行,并且得到控件的值
ASP.NET给Table动态添加控件并且得到控件的值 由于跟老师做一个小的项目,可是我自己又不太懂js,所以一直为动态建立表格并且能动态的取值和赋值感到苦恼.起初在网上找到了一些js资源,解决了动态 ...
- 如何给动态添加的form表单控件添加表单验证
最近使用jQuery Validate做表单验证很方便,api地址为http://www.runoob.com/jquery/jquery-plugin-validate.html 但是在使用的时候也 ...
- asp.net 动态添加多个用户控件
动态添加多个相同用户控件,并使每个用户控件获取不同的内容. 用户控件代码: 代码WebControls using System; using System.Collections.Generic; ...
- WPF 动态添加控件以及样式字典的引用(Style introduction)
原文:WPF 动态添加控件以及样式字典的引用(Style introduction) 我们想要达到的结果是,绑定多个Checkbox然后我们还可以获取它是否被选中,其实很简单,我们只要找到那几个关键的 ...
- WPF中TreeView控件数据绑定和后台动态添加数据(一)
数据绑定: 更新内容:补充在MVVM模式上的TreeView控件数据绑定的代码. xaml代码: <TreeView Name="syntaxTree" ItemsSourc ...
- C# WPF后台动态添加控件(经典)
概述 在Winform中从后台添加控件相对比较容易,但是在WPF中,我们知道界面是通过XAML编写的,如何把后台写好的控件动态添加到前台呢?本节举例介绍这个问题. 这里要用到UniformGrid布局 ...
- Android 在布局容器中动态添加控件
这里,通过一个小demo,就可以掌握在布局容器中动态添加控件,以动态添加Button控件为例,添加其他控件同样道理. 1.addView 添加控件到布局容器 2.removeView 在布局容器中删掉 ...
随机推荐
- noip2016 天天爱跑步
没看过正解..应该是些乱七八糟想不出来的东西 解法1: 首先,必须要做的是将每条路径拆成2个直的路径 那么对于那条从深度大的到深度小的路径 dep[x]-dep[y]应该等于观察时间 那么就可以在这些 ...
- 【Java】 剑指offer(35) 复杂链表的复制
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请实现函数ComplexListNode* Clone(Compl ...
- Unity报错 : BCE0004: Ambiguous reference 'preview': CameraMotionBlurEditor.preview, UnityEditor.Editor.preview.
建立项目版本为Unity4.6,改为5.3.4版本,运行项目报如下错误: “BCE0004: Ambiguous reference 'preview': CameraMotionBlurEditor ...
- python连接mysql、sqlserver、oracle、postgresql数据库的一些封装
包括python连接数据库,以及django下配置连接数据库 # -*- coding:utf-8 -*- import psycopg2 import pymysql import pymssql ...
- Web轻量级扫描工具Skipfish
Web轻量级扫描工具Skipfish 1. Skipfish 简介 2. Skipfish 基本操作 3.身份认证 一. Skipfish 简介 Skipfish是一款主动的Web应用程序安全侦察工具 ...
- js基础梳理-究竟什么是变量对象,什么是活动对象?
首先,回顾下上篇博文中js基础梳理-究竟什么是执行上下文栈(执行栈),执行上下文(可执行代码)?的执行上下文的生命周期: 3.执行上下文的生命周期 3.1 创建阶段 生成变量对象(Variable o ...
- 动态规划-线性dp-hdu-4055
https://www.cnblogs.com/31415926535x/p/10423047.html 这道题是大连的某一年的现场赛的题hdu-4055 ,,,刚开始做线性dp的题,,看了好半天才看 ...
- python常用模块之时间模块
python常用模块之时间模块 python全栈开发时间模块 上次的博客link:http://futuretechx.com/python-collections/ 接着上次的继续学习: 时间模块 ...
- android studio java工程 报错
作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com E-mail: 313134555 @qq.com android studio java工程 ...
- 2016年3月9日Android实习日记
1. 解决 org.eclipse.swt.SWTException: Graphic is disposed 问题. 参考:http://www.xuebuyuan.com/1896964.html ...