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()的方法来实现。

相关推荐
不吃土豆的马铃薯10 分钟前
C++ 高性能网络缓冲区 Buffer 源码解析
linux·服务器·开发语言·网络·c++
数据法师25 分钟前
QuickSay :基于 Qt 的轻量级快捷短语管理工具
开发语言·qt
caimouse38 分钟前
Reactos 第1章 概述
c语言·开发语言·架构
.千余1 小时前
【C++】C++继承入门(下):友元、静态成员与菱形继承的底层逻辑
开发语言·c++·笔记·学习·其他
小短腿的代码世界1 小时前
行情快照与增量更新引擎:Qt在高频交易数据分发中的核心架构——你的行情推送为什么延迟了500ms?
开发语言·qt·架构
初中就开始混世的大魔王1 小时前
6 Fast DDS-传输层
开发语言·c++·中间件·信息与通信
啊森要自信1 小时前
【GUI自动化测试】控件、鼠标键盘操作与多场景自动化
c语言·开发语言·python·adb·ipython
花北城1 小时前
【C#】ABP框架服务端开发
开发语言·c#·abp
电商API_180079052472 小时前
Python 实现闲鱼商品列表批量采集,接口异常重试机制搭建
大数据·开发语言·数据库·爬虫·python
DogDaoDao2 小时前
深入理解 Qt:从原理到实战的全景指南
开发语言·qt·程序员