C# WPF上位机开发(动态添加控件)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        写图形界面软件的时候,我们经常会遇到一种情况。那就是图形界面上面,显示的控件可能是不定的。有可能多,也有可能少,具体显示多少内容需要根据配置文件而来。这样对我们来说,其实是有点尴尬的。毕竟,大多数场景,软件打开来之后,什么地方配置哪些内容,都是已经确定好的。

        不过没关系,c# wpf也考虑到了这一点,我们可以通过编写代码的方法进行灵活添加和设置。毕竟,在xaml文件留下来的只是一个空的grid界面而已。

1、xaml界面设计

        xaml界面就比较简单,为了显示方便,我们设计了两行。第一行的高度为100,剩下来的空间全部留给第二行。为了放置控件,还特地给这个grid起了一个名字叫mainGrid。

<Window x:Class="WpfApp.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"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="600">
    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="100" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid  Grid.Row="1" x:Name="mainGrid">
            <!-- Add your own layout here -->
        </Grid>
    </Grid>
</Window>

2、初始化按钮

        目前这个case只是为了演示如何添加控件。添加的内容比较少,就是一个按钮。首先初始化按钮,设置按钮的属性,分别是content、width和height。同时还给这个按钮配置了一个回调函数。按钮设置好了,再创建一个stack panel,将按钮装在这个stack panel里面。最后,也是最重要的一步,就是把stack panel保存到mainGrid的space里面,这样就实现了整个界面的部分。

        public MainWindow()
        {
            InitializeComponent();
            AddButtonDynamically();
        }

        private void AddButtonDynamically()
        {
            // 创建一个新的Button控件
            Button newButton = new Button();

            // 设置Button的属性
            newButton.Content = "Click me!";
            newButton.Width = 100;
            newButton.Height = 100;

            // 为Button添加Click事件处理程序
            newButton.Click += NewButton_Click;

            // 创建一个StackPanel并将Button添加到其中
            StackPanel stackPanel = new StackPanel();
            stackPanel.Children.Add(newButton);

            // 将StackPanel添加到窗口中的Grid中
            mainGrid.Children.Add(stackPanel);
        }

        按钮回调函数如下所示,

        // Click事件处理程序
        private void NewButton_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Button Clicked!");
        }

3、多线程中更新界面

        除了动态添加空间之外,另外一部分要注意的,就是界面部分和多线程的更新。启动一个线程很简单,不过如果如果在新的线程里面更新界面,这个是需要注意下的。为了说明这个问题,我们更新下界面,

<Window x:Class="WpfApp.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"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="600">
    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="100" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Label x:Name="text" Grid.Row="0" Content="0" HorizontalAlignment="Center">
        </Label>
        <Grid  Grid.Row="1" x:Name="mainGrid">
            <!-- Add your own layout here -->
        </Grid>
    </Grid>
</Window>

        这个界面和之前的区别就是多了一个Label,放在了row 0当中,命名为text。解析来为了说明多线程,首先我们添加多线程库,

using System.Threading;

        添加完了之后,就可以创建线程,启动线程了。一般每个线程都有对应的线程入口函数,

        public MainWindow()
        {
            InitializeComponent();
            AddButtonDynamically();

            Thread newThread = new Thread(new ThreadStart(ThreadMethod));
            newThread.Start();
        }

        private void ThreadMethod()
        {
            int cnt = 0;

            while(true)
            {
                cnt += 1;
                Dispatcher.Invoke(() =>
                {
                    // 在UI线程上执行操作(如果需要)
                    text.Content = Convert.ToString(cnt);
                });

                Thread.Sleep(1000);
            }
        }

        多线程的操作很正常,这里面需要注意的就是text更新的部分。也就是说,如果需要更新界面的内容,最好用Dispatcher.Invoke()的方法来实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/246139.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JupyterNotebook VS JupyterLab 如果jupyter安装成功,点击jupyterlab即可进入lab环境

简介 JupyterNotebook 是一个款以网页为基础的交互计算环境&#xff0c;可以创建Jupyter的文档&#xff0c;支持多种语言&#xff0c;包括Python, Julia, R等等。一般来说&#xff0c;如果是使用R语言的话&#xff0c;使用Rstudio居多&#xff0c;使用Python的话&#xff0c;使…

消息队列 - RabbitMQ

消息队列 - RabbitMQ 1. 初识 MQ1.1 同步调用1.2 异步调用1.3.技术选型 2. RabbitMQ2.1 安装2.2 收发信息2.2.1 交换机(Exchange)2.2.2 队列2.2.3 绑定关系2.2.4 发送消息 2.3 数据隔离 相关文章: SpringAMQP 快速入门 RabbitMQ 如何保证消息可靠性 1. 初识 MQ 微服务一旦拆分…

beyond compare文件夹比较时候文本乱码问题解决

“格式”&#xff0c;在下面的左侧编码重写和右侧编码覆盖选择 GB2312/UTF-8/GBK&#xff0c;这个可以根据自己喜好和文本自身的encode选择。

C++ 指针基础

指针的定义 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h>int main() {int a 10;printf("%p\n", &a); // &a 表示取&#xff08;a&#xff09;的地址 000000842FD9FB64// 存放指针&#xff08;地址&#xff09;的变量就是指针变量&#xff0c…

Java中的链表

文章目录 前言一、链表的概念及结构二、单向不带头非循坏链表的实现2.1打印链表2.2求链表的长度2.3头插法2.4尾插法2.5任意位置插入2.6查找是否包含某个元素的节点2.7删除第一次出现这个元素的节点2.8删除包含这个元素的所以节点2.9清空链表单向链表的测试 三、双向不带头非循坏…

spring 笔记三 Spring与Web环境集成

文章目录 Spring与Web环境集成ApplicationContext应用上下文获取方式导入Spring集成web的坐标置ContextLoaderListener监听器通过工具获得应用上下文对象SpringMVC概述SpringMVC快速入门 Spring与Web环境集成 ApplicationContext应用上下文获取方式 应用上下文对象是通过new …

leetcode面试经典150题——36 旋转图像

题目&#xff1a; 旋转图像 描述&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#x…

中国经济增长:全球复苏的引擎

近年来&#xff0c;中国经济以其强劲的增长势头成为全球经济的重要引擎。中国的经济崛起不仅对自身国家发展具有重要意义&#xff0c;而且也对全球经济复苏和稳定有着积极影响。本文将从多个角度探讨中国经济增长对全球经济的影响及其作为全球复苏的引擎。 首先&#xff0c;中国…

《使用ThinkPHP6开发项目》 - ThinkPHP6使用JWT生成Token

《使用ThinkPHP6开发项目》 - 登录接口一-CSDN博客 《使用ThinkPHP6开发项目》 - 登录接口二-CSDN博客 《使用ThinkPHP6开发项目》 - 登录接口三【表单验证】-CSDN博客 登录接口成功后返回Token&#xff0c;便于其他需要验证用户登录的接口携带Token进行请求校验 这里Think…

基于ssm网络安全宣传网站设计论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本网络安全宣传网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

SI24R03国产自主可控RISC-V架构MCU低功耗2.4GHz收发芯片SoC

目录 RISC-V架构的优势SI24R03/04特性射频收发器模块特征MCU 模块特征 其他特征 RISC-V架构的优势 相对于目前主流的英特尔X86架构及ARM等架构来说&#xff0c;RISC-V架构具有指令精简、模块化、可扩展、开源、免费等优点。RISC-V的基础指令集只有40多条&#xff0c;加上其他基…

爬虫的分类

爬虫的分类 网络爬虫按照系统结构和实现技术&#xff0c;大致可分为4类&#xff0c;即通用网络爬虫、聚焦网络爬虫、增量网络爬虫和深层次网络爬虫。 1.通用网络爬虫&#xff1a;搜索引擎的爬虫 比如用户在百度搜索引擎上检索对应关键词时&#xff0c;百度将对关键词进行分析…

比特币价格创新高:加密货币的崛起与未来

一、引言 近年来&#xff0c;比特币的价格一路上涨&#xff0c;引起了全球投资者和市场的广泛关注。作为最早一批区块链技术应用案例之一&#xff0c;比特币的成功带动了整个加密货币市场的兴起。本文将探讨比特币价格创新高的原因、加密货币的崛起以及未来发展趋势。 二、比特…

ChatGPT热门项目

1.智能GPT 项目地址&#xff1a;智能GPT&#xff1a;你只要提供OpenAI的API Key&#xff0c;那么它就可以根据你设定的目标&#xff0c;采用Google搜索、浏览网站、执行脚本等方式 主要语言&#xff1a;Python 推荐理由&#xff1a;这是由开发者Significant Gravitas推出的项目…

【C++练级之路】【Lv.4】类和对象(下)(初始化列表,友元,static成员,编译器的优化)

目录 一、再谈构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字 二、static成员2.1 概念2.2 特性 三、友元3.1 引入3.2 友元函数3.2.1 概念3.2.2 特性 3.3 友元类3.3.1 概念3.3.2 特性 四、内部类4.1 概念4.2 特性 五、匿名对象六、编译器的优化6.1 传参优化6.1.1 …

Java EE 网络之网络初识

文章目录 1. 网络发展史1.1 独立模式1.2 网络互连1.3 局域网 LAN1.4 广域网 WAN 2. 网络通信基础2.1 IP 地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 什么是协议分层2.5.2 分层的作用2.5.3 OSI七层协议2.5.4 TCP/IP五层协议2.5.5 网络设备所在分层 2.6 分装和分用 …

简单的教务系统

#include <stdio.h> #include <string.h> #define N 20 int i,j,n,m,lll0,renshu6; double zcj[N]{0};struct stu{ char num[10]; //学号char name[10]; //姓名char sex; //姓别double score[3]; //3 门课的成绩double sum; //3 门课的总分double aver; //3 门课的…

【深度学习目标检测】五、基于深度学习的安全帽识别(python,目标检测)

深度学习目标检测方法则是利用深度神经网络模型进行目标检测&#xff0c;主要有以下几种&#xff1a; R-CNN系列&#xff1a;包括R-CNN、Fast R-CNN、Faster R-CNN等&#xff0c;通过候选区域法生成候选目标区域&#xff0c;然后使用卷积神经网络提取特征&#xff0c;并通过分类…

超聚变服务器(原华为服务器)网站模拟器

一、超聚变服务器&#xff08;原华为服务器&#xff09;网站模拟器&#xff1a; 原来了解服务器可以从他的网站上进行了解&#xff0c;模拟器做的很好了。 https://support.xfusion.com/server-simulators/ 有很多的模拟器&#xff0c;今天主要看下BMC的设置 有很多的在线工具…

vue中element-ui日期选择组件el-date-picker 清空所选时间,会将model绑定的值设置为null 问题 及 限制起止日期范围

一、问题 在Vue中使用Element UI的日期选择组件 <el-date-picker>&#xff0c;当你清空所选时间时&#xff0c;组件会将绑定的 v-model 值设置为 null。这是日期选择器的预设行为&#xff0c;它将清空所选日期后将其视为 null。但有时后端不允许日期传空。 因此&#xff…