求教 C#窗体中动态添加了Panel,再如何动态的在Panel中添加文本框控件呢?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求教 C#窗体中动态添加了Panel,再如何动态的在Panel中添加文本框控件呢?相关的知识,希望对你有一定的参考价值。
根据我商品记录数动态的添加panel,每条记录添加一个panel,每个panel作为一个模块儿,其中动态放置一些文本框、按钮,请大神帮帮忙!目前效果如下,成功的添加了panel,但是不知道怎么在panel中动态增加文本框等控件。 private void GoShoppingCar_Load(object sender, EventArgs e) for (int i = 0; i < listPro.Count; i++) Panel panel = new Panel(); TextBox tb = new TextBox(); panel.Name = "panelX" + i.ToString(); panel.TabIndex = i; panel.Width = 500; panel.BackColor = Color.Green; panel.Location = new Point(30,30+i*60); panel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.panel1.Controls.Add(panel);
inti=0;
privatevoidbutton1_Click(objectsender,EventArgse)
TextBoxtb=newTextBox();
tb.Name="tb_"+i.ToString();
tb.Text=(i+2).ToString();
tb.Width=200;
tb.Height=30;
tb.Location=newPoint(0,0+i*30);
i++;
this.panel1.Controls.Add(tb);
扩展资料
C#的优点
C#将实现更多的函数式编(FP)程概念,TypeClasses就是FP概念之一。在函数式编程中,TypeClasses允许您在类型上添加一组操作,但不实现它。由于实现是在其他地方完成的,这是一种多态,它比面向对象编程语言中的class更灵活。
TypeClasses和C#接口具有相似的用途,但它们的工作方式有所不同,在某些情况下,由于处理固定类型而不是继承层次结构,因此TypeClasses更易于使用。
参考资料来源:百度百科—c#
参考技术A1、首先需要建一个form载体,承载panel。
2、在工具箱中找到对应的panel控件,通过拖拽,放到form上。
3、右键属性,设置panel的背景色,方便标识。
4、在panel上绑定控件鼠标划出的方法。
5、做一个按钮,绑定一个panel的显示事件。
6、鼠标划出就会隐藏panel,点击按钮panel就会显示。
参考技术B这个简单,我没看你的代码。 我只看了你的标题,我举个简单的例子哈。
Panel pan1= new Panel();//此处设置你的lab1的属性,状态,背景,以及事件等等
Label lab1=new Label();
//此处设置你的lab1的属性,状态,背景,以及事件等等
lab1.Text="这个是panel控件里面的label控件";
pan1.Controls.Add(lab1);//把lab1的容器设置为pan1,绑定在一起
lab1.Location=new Point(0,0);//设置lab1控件在pan1中的位置,相对于pan1而不是整个窗口,所以这里我的代码就是把lab1放在了pan1的左上角
其他的代码你自己补全哈
这种添加只是把labl添加到了父panl上,并没有添加到子panl上,还是没有达到想要的效果。
能帮忙实现下面这种效果吗?
你把我上面的代码的所谓的父panel改成子panel名字不就得了???
panel1里面有一个panel2,panel2里面还有一个label,你就这样
panel1.Controls.Add(panel2);
panel2.Controls.Add(label);
这样就可以啦
您说的向子panel中添加的思路我能明白,但是程序中这一点过不去,麻烦您给看下:
当然过不去了,你这个conNmae只是一个字符串类型,this.根本找不到。。其他的我没看,就单看你这一句话,你的conName只是控件panel的名字而已,所以你应该用panel。写成下面这样:panel.Controls.Add(tb);
追问对的,所以这样做就添加不到子panel中了,其实一直纠结的问题在这里。不过还是非常感谢您,暂时没有分了,有了给您奉上!
追答没事 给个采纳就行
本回答被提问者采纳C# WPF后台代码动态添加控件
在wpf开发中,虽然可以通过XMAL编写炫酷的界面,但是有时候需要动态定义控件即:前台界面控件数量或者类型需要解析的数据或者其它条件确认再生成,这时候我们就需要通过后台cs中编写代码实现这一功能。
01
—
功能演示
02
—
功能说明
以上演示部分我们可以看到我前台的部分界面在窗体加载后并没有显示,而是选择文件解析后自动产生的,这种场景有时候也挺常用,特别是有大量同类型的数据显示到同类型的控件中时,我们就可以通过导入txt、Xml等文件的形式然后自动生成. 本地主要是举例演示实现这一功能,使用场景造得可能并不恰当,大家忍受下。
03
—
源码实现
前台代码:
<UserControl x:Class="Caliburn.Micro.Hello.DynamicalView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Caliburn.Micro.Hello"
xmlns:cal="http://www.caliburnproject.org" xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1.5*" />
<RowDefinition Height="8.5*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Grid.Row="0" Grid.ColumnSpan="2">
<TextBox Width="500" Height="30" Margin="3" Text="Binding FilePath" FontSize="14"
FontStyle="Normal" IsReadOnly="True" />
<Button Content="..." Margin="3" MinWidth="50"
cal:Message.Attach="[Event Click] = [Action SelectFile()]" />
</StackPanel>
<GroupBox Grid.Column="0" Grid.Row="1" Margin="3">
<GroupBox.Header>
<dxlc:LayoutItem Label="Student" Foreground ="Green" />
</GroupBox.Header>
<dxlc:LayoutControl>
<Grid HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="0"
cal:Message.Attach="[Event Loaded] = [Action StudentGridLoaded($source)]" />
</dxlc:LayoutControl>
</GroupBox>
<GroupBox Grid.Column="1" Grid.Row="1" Margin="3">
<GroupBox.Header>
<dxlc:LayoutItem Label="Teacher" Foreground ="Blue" />
</GroupBox.Header>
<dxlc:LayoutControl>
<Grid HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="0"
cal:Message.Attach="[Event Loaded] = [Action TeacherGridLoaded($source)]" />
</dxlc:LayoutControl>
</GroupBox>
</Grid>
</UserControl>
这里使用了Caliburn.Micro框架,所以需要引用名称空间
xmlns:cal="http://www.caliburnproject.org"
因为控件数量不确定,需要显示不全时行列可以拖动,实现这一功能只需要把控件包裹进:<dxlc:LayoutControl>就可以。
后台代码:
using DevExpress.Xpf.Editors;
using PropertyChanged;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Forms;
using Binding = System.Windows.Data.Binding;
using HorizontalAlignment = System.Windows.HorizontalAlignment;
using Label = System.Windows.Controls.Label;
namespace Caliburn.Micro.Hello
[AddINotifyPropertyChangedInterface]
public class DynamicalViewModel : Screen, IViewModel
private readonly AutoResetEvent StudentGridLoad = new AutoResetEvent(false);
private readonly AutoResetEvent TeacherGridLoad = new AutoResetEvent(false);
public string FilePath get; set; = @"D:\\test.txt";
public List<PersonInfoDTO> PersonInfoList = new List<PersonInfoDTO>();
public PersonInfo PersonInfo get; set;
public DynamicalViewModel()
DisplayName = "DynamicalControls";
public void DispalyReuslt()
Task.Run(() =>
ParseData();
Execute.OnUIThread(() =>
AddGridControl();
);
);
private void ParseData()
var lines = File.ReadAllLines(FilePath);
foreach (string line in lines)
var strs = line.Split(':');
if (strs.Count() > 1)
var infos = strs[1].Split(',');
PersonInfoList.Add(new PersonInfoDTO()
InfoType = strs[0],
PersonInfo = new PersonInfo()
Name = infos[0],
Sex = infos[1],
Age = Convert.ToInt32(infos[2])
);
public void SelectFile()
string defaultInputFolder = @"D:\\test.txt";
OpenFileDialog fileDialog = new OpenFileDialog();
if (defaultInputFolder != null)
fileDialog.InitialDirectory = defaultInputFolder;
fileDialog.Multiselect = false;//该值确定是否可以选择多个文件
fileDialog.Title = "请选择ReportFile文件";
fileDialog.Filter = "文本文件(*.txt)|*.txt";
if (fileDialog.ShowDialog() == DialogResult.OK)
FilePath = fileDialog.FileName;
DispalyReuslt();
private Grid StudentGrid get; set;
private Grid TeacherGrid get; set;
public void StudentGridLoaded(object sender)
StudentGrid = (Grid)sender;
public void TeacherGridLoaded(object sender)
TeacherGrid = (Grid)sender;
int studentRowIndex = 0;
int studentColumnIndex = 0;
int teacherRowIndex = 0;
int teacherColumnIndex = 0;
private void AddGridControl()
int StudentConut = 0;
int TeacherCount = 0;
foreach (var item in PersonInfoList)
if (item.InfoType == "老师")
TeacherCount++;
else
StudentConut++;
StudentGrid.Children.Clear();
StudentGrid.ColumnDefinitions.Clear();
StudentGrid.RowDefinitions.Clear();
TeacherGrid.Children.Clear();
TeacherGrid.ColumnDefinitions.Clear();
TeacherGrid.RowDefinitions.Clear();
var gridColumns = 4;
var successGridRows = Math.Ceiling(StudentConut / 2.0);
var failGridRows = Math.Ceiling(TeacherCount / 2.0);
//添加grid列
for (int i = 0; i < gridColumns; i++)
var successColumnDefinition = new ColumnDefinition();
StudentGrid.ColumnDefinitions.Add(successColumnDefinition);
var failedColumnDefinition = new ColumnDefinition();
TeacherGrid.ColumnDefinitions.Add(failedColumnDefinition);
//添加grid行
for (int i = 0; i < successGridRows; i++)
var successRowDefinition = new RowDefinition();
StudentGrid.RowDefinitions.Add(successRowDefinition);
successRowDefinition.Height = new GridLength(30, GridUnitType.Pixel);//绝对尺寸
for (int i = 0; i <= failGridRows; i++)
var failedRowDefinition = new RowDefinition();
TeacherGrid.RowDefinitions.Add(failedRowDefinition);
failedRowDefinition.Height = new GridLength(30, GridUnitType.Pixel);//绝对尺寸
int rowIndex = 0;
int columnIndex = 0;
UIElement uIElement = new UIElement();
foreach (var item in PersonInfoList)
if (item.InfoType == "学生")
if (studentColumnIndex / 4 == 1)
studentColumnIndex = 0;
studentRowIndex++;
rowIndex = studentRowIndex;
columnIndex = studentColumnIndex;
else
if (teacherColumnIndex / 4 == 1)
teacherColumnIndex = 0;
teacherRowIndex++;
rowIndex = teacherRowIndex;
columnIndex = teacherColumnIndex;
if (columnIndex % 2 == 0)
Label label = new Label();
label.HorizontalAlignment = HorizontalAlignment.Right;
label.VerticalAlignment = VerticalAlignment.Center;
label.Width = 100;
label.Content = item.PersonInfo.Name;
label.SetValue(Grid.RowProperty, rowIndex);
label.SetValue(Grid.ColumnProperty, columnIndex);
uIElement = label;
if (item.InfoType == "学生")
StudentGrid.Children.Add(uIElement);
studentColumnIndex++;
columnIndex = studentColumnIndex;
else
TeacherGrid.Children.Add(uIElement);
teacherColumnIndex++;
columnIndex = teacherColumnIndex;
TextEdit textBox = new TextEdit();
textBox.HorizontalAlignment = HorizontalAlignment.Left;
textBox.VerticalAlignment = VerticalAlignment.Center;
textBox.Name = item.PersonInfo.Name;
textBox.Width = 100;
textBox.Height = 25;
textBox.SetValue(Grid.RowProperty, rowIndex);
textBox.SetValue(Grid.ColumnProperty, columnIndex);
var path = item.PersonInfo.GetType().GetProperty("Age");
Binding binding = new Binding()
Source = item.PersonInfo,
Path = new PropertyPath(path),
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
;
textBox.SetBinding(TextEdit.TextProperty, binding);
uIElement = textBox;
if (item.InfoType == "学生")
StudentGrid.Children.Add(uIElement);
studentColumnIndex++;
columnIndex = studentColumnIndex;
else
TeacherGrid.Children.Add(uIElement);
teacherColumnIndex++;
columnIndex = teacherColumnIndex;
数据模型:
public class PersonInfo
public string Name get; set;
public int Age get; set;
public string Sex get; set;
public override string ToString()
string report = $"[Name] = [Name],[Age] = [Age],[Sex] = [Sex]";
return report;
public class PersonInfoEven : PersonInfo
public class PersonInfoDTO
public string InfoType get; set;
public PersonInfo PersonInfo get; set;
这里需要注意一些地方:
①首先StudentGridLoaded和TeacherGridLoaded是在viewmodel初始化完成后才加载的,所以在构造函数执行完后还是null;
②加载控件和解析数据比较慢我放在了线程Task.Run运行,但是线程中更新界面又需要用委托实现,这里CM给我们封装了方法
Execute.OnUIThread(() => );
③:grid行列添加:
var successColumnDefinition = new ColumnDefinition();
StudentGrid.ColumnDefinitions.Add(successColumnDefinition);
var successRowDefinition = new RowDefinition();
StudentGrid.RowDefinitions.Add(successRowDefinition);
④通过代码生成TextEdit,bing数据并添加到grid中:
TextEdit textBox = new TextEdit();
textBox.HorizontalAlignment = HorizontalAlignment.Left;
textBox.VerticalAlignment = VerticalAlignment.Center;
textBox.Name = item.PersonInfo.Name;
textBox.Width = 100;
textBox.Height = 25;
textBox.SetValue(Grid.RowProperty, rowIndex);
textBox.SetValue(Grid.ColumnProperty, columnIndex);
var path = item.PersonInfo.GetType().GetProperty("Age");
Binding binding = new Binding()
Source = item.PersonInfo,
Path = new PropertyPath(path),
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
;
textBox.SetBinding(TextEdit.TextProperty, binding);
uIElement = textBox;
TeacherGrid.Children.Add(uIElement);
⑤遍历grid中的控件:
foreach (UIElement uiElement in failedParsedGrid.Children)
if (uiElement is TextEdit)
TextEdit textBox = uiElement as TextEdit;
switch (textBox.Name)
//todo
⑥通过反射遍历属性:
foreach (PropertyInfo info in PersonInfo.GetType().GetProperties())
var itemValue = info.GetValue(PersonInfo);
// TO DO
以上是关于求教 C#窗体中动态添加了Panel,再如何动态的在Panel中添加文本框控件呢?的主要内容,如果未能解决你的问题,请参考以下文章
c#在panel中动态增加控件时怎样自动调整panel的行列大小
C# Winform自定义控件加载到主窗体中之后,自定控件上面的空间 怎么和主窗体上其他控件交互?