frame
Introduction
The following are several common interface development frameworks based on .Net, all provided by Microsoft. The following introduction is generated by GPT
WinForms (Windows Forms
WPF (Windows Presentation Foundation)
UWP (Universal Windows Platform)
MAUI (Multi-platform App UI)
- WinForms(Windows Forms):
- Introduction: WinForms is a UI framework provided by Microsoft for developing Windows desktop applications. It uses a simple drag-and-drop interface for user interface building and is based on the .NET framework.
- main feature:
- Rapid application development (RAD) using visual designers.
- Event-driven programming model.
- Direct integration with Windows API.
- WPF(Windows Presentation Foundation):
- Introduction: WPF is a framework for building Windows desktop applications with rich user interfaces. It provides a more modern and flexible UI development approach compared to WinForms.
- main feature:
- Powerful data binding and template system.
- Resolution independent vector graphics.
- Extensible and customizable controls.
- Separation of UI and business logic.
- UWP(Universal Windows Platform):
- Introduction: UWP is a platform introduced by Microsoft for creating universal applications that can run on various Windows devices, including PCs, tablets, mobile phones, Xbox, HoloLens, etc. It is part of the Windows 10 ecosystem.
- main feature:
- Adaptive user interface adapts to different device shapes.
- Security and performance improvements.
- Integration with Windows 10 features like Cortana and Live Tiles.
- MAUI(Multi-platform App UI):
- Introduction: MAUI is a modern cross-platform framework introduced by Microsoft for building native applications for iOS, Android, Windows and macOS from a single code base. It is an evolution of Xamarin.Forms and is part of the .NET MAUI stack.
- main feature:
- A single code base works on multiple platforms.
- Supports native UI controls for each platform.
- Integrated with .NET 6 and above.
- Available for a variety of devices, including desktop and mobile.
choose
winform is too old
For uwp, we will use windows computers, there is no need
Maui is bloated because it is cross-platform
So we choose WPF. The following article also mainly talks about WPF.
UI
Design ideas
First, design the layout based on function
Then if the project is relatively large, you should consider the selection of design patterns and separate the front and back ends.
control
Because UI development is based on interfaces and controls, and the controls we commonly use are all similar, you can just consult the documentation when needed.
Commonly used
Information label
Editing class text editing textbox status editing checkbox
buttonbutton _
Add method
Drag and drop to add
code addition
layout
position
anchor, anchor an edge
dock, dock, press the pop-up options to set
Rewrite the Onlayout function (triggered when layout changes)
Group
Panel, multi-level layout, binds controls to panels to facilitate combination of overall control
event
That is, the interface acquisition operation is passed to the backend for corresponding
winform
Project structure
VS chooses to create form applications based on C# and .Net
Run it directly and you will see an empty interface.
Then you can look at solution management and you can see that there are
- Form1.cs is an interface design file. Open it directly to display the UI. You can right-click to view the code.
- Form1.Designer.cs, the underlying code automatically generated by our design, is called by the design file
- The above two are the same class divided into different files. The former handles events and the latter handles layout.
- Form.resx
- program.cs program entry
new Form1()
to instantiate our window
Add controls by dragging and add events through attributes. The main code of the interface is in the designer. It is best not to touch it. The required changes are all in Form1.cs.
Because there are few application scenarios, we don’t study in depth.
WPF
WPF Getting Started Basic Tutorial Series
Project structure
- App.xaml
StartupUri
sets the startup window andResources
style template - MainWindow.xaml drag-and-drop layout can be rendered in real time
Then we run the project directly and you can see a blank window
xaml
xaml is an XML-based markup language used to define UI and attributes. The corresponding cs file will be generated based on xaml.
Just the following syntax
<CMD ..... />
Equivalent to<CMD>.....</CMD>
Let’s look at ``MainWindow.xaml`
<Window x:Class="WPF.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:WPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
Explained below
<Window>
element:x:Class="WPF.MainWindow"
: This attribute specifies the class name of the window. Here, the class name of the window isMainWindow
, which corresponds to the class name in the code. This attribute is typically used to associate XAML files with classes in back-end code (such as C#).
- Namespace declaration:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
: Specifies the default XML namespace, which is used to define basic rendering elements of WPF, such as windows, panels, buttons, etc.xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
:Specifies a XAML-specific namespace, which contains some special attributes for XAML files.
- Additional namespace declaration:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
: Namespace for the Blend tool, which is commonly used for design and interactive development.xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
: Defines some properties used to maintain compatibility between different XAML compiler versions.
- Local namespace declaration:
xmlns:local="clr-namespace:WPF"
: Specifies a local namespace, which isWPF
associated with the namespace.WPF
This allows classes and resources defined in the namespace to be referenced in XAML files .
mc:Ignorable="d"
:- This attribute tells the compiler to ignore errors when handling unknown
d
prefixes. In this case,d
is the Blend tool namespace, andIgnorable
the attribute allows ignoring this unknown prefix without affecting compilation.
- This attribute tells the compiler to ignore errors when handling unknown
- Window property settings:
Title="MainWindow"
: Set the title of the window to "MainWindow".Height="450"
andWidth="800"
: Set the height and width of the window to 450 and 800 respectively.
layout
Everything can be changed through properties
-
StackPanel
StackPanel is mainly used to arrange elements vertically or horizontally and place a limited number of elements within the available size of the container. The total size of the elements (length/height) is not allowed to exceed the size of the StackPanel, otherwise the excess part will not be visible.
-
WrapPanel
The default arrangement direction of WrapPanel is opposite to that of StackPanel, and the Orientation of WrapPanel defaults to Horizontal. WrapPanel has the functions of StackPanel and can automatically adapt to the width and height of the container to wrap rows and columns after the size is changed .
-
DockPanel
docked layout
Internal controls are laid out through the DockPanel.Dock property, and Left is added by default.
DockPanel has a LastChildFill attribute, which defaults to true. The effect of this attribute is that when the last element in the container is the last element, the element fills all the space of the DockPanel by default.
-
Grid
Grid has the ability to divide space.
RowDefinitions / ColumnDefinitions are used to assign rows and columns to the Grid.
Row / Column to determine the position of the control
ColumnSpan / RowSpan to set the control length and width
Divide and distribute as follows
In the size, auto means the same as the controls in the grid, * means the proportion of the remaining parts of auto
<Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="37*" /> <RowDefinition Height="138*" /> <RowDefinition Height="175*" /> <RowDefinition Height="175*" /> <RowDefinition Height="175*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="58*" /> <ColumnDefinition Width="58*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="362*" /> <ColumnDefinition Width="71*" /> </Grid.ColumnDefinitions> <Label Grid.Column="1" Content="Label" Grid.ColumnSpan="1" Grid.RowSpan="3" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Center"/>
control
-
ContentControl class
The content attribute is Content, which can only be set once, but can be nested.
-
ItemsControl class
Most of these controls belong to the display list class data, and the way to set the data source is generally set through ItemSource.
-
HeaderedContentControl 类
Compared with ContentControl, this type of control can set Content, as well as Header with title. Like the more common grouping controls GroupBox and TabControl sub-element TabItem, they are all controls with titles and content.
-
Commonly used controls
- TextBlock: Used to display text, static text that does not allow editing.
- TextBox: A control used to input/edit content. Its function is similar to the TextBox in winform. Text sets the content to be input and displayed.
- Button: Simple button, Content displays text, Click can set click events, and Command can set background binding commands.
- ComboBox: drop-down box control, ItemSource sets the data source of the drop-down list, and can also display settings.
event
Set it in MainWindow.xaml to trigger the function
namespace WPF
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();//界面显示
}
//添加的事件函数
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
}
style
Styleable
- Font(FontFamily)
- Font size (FontSize)
- Background color(Background)
- Font color (Foreground)
- Margin
- HorizontalAlignment
- VerticalAlignment
Add it globally to <Application.Resources> in the app
Partially add <Window.Resources> in the current xaml (same level as grid)
<Style x:Key="TextBlockStyle" TargetType="TextBlock">
<Setter Property="Text" Value="TextBlock" />
<Setter Property="Height" Value="30" />
<Setter Property="Width" Value="60" />
<Setter Property="Background" Value="Red" />
</Style>
use
<TextBlock TextWrapping="Wrap" Style="{
StaticResource TextBlockStyle}"/>
<!--这里也可以再修改样式,优先级高于Style-->
trigger
The same style is executed when the corresponding event is triggered.
<Style x:Key="TextBlockStyle" TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
template
Control template
There are only so many changes we can make in styles,
So you can right-click the control and edit the copy to create a new control.
How to add rounded corners to a button
After editing the copy, add the Border tag to the generated copy.CornerRadius="10"
Then set the buttonStyle="{StaticResource ButtonStyle1}"
Data template
CellTemplate
Table implementation, using grid
The template is placed directly in. This table has three columns and two buttons in the fourth column.
<DataGrid Name="gd" AutoGenerateColumns="False" CanUserSortColumns="True" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding UserName}" Width="100" Header="学生姓名"/>
<DataGridTextColumn Binding="{Binding ClassName}" Width="100" Header="班级名称"/>
<DataGridTextColumn Binding="{Binding Address}" Width="200" Header="地址"/>
<DataGridTemplateColumn Header="操作" Width="100" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
<Button Content="编辑"/>
<Button Margin="8 0 0 0" Content="删除" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Bind data, behind InitializeComponent();
public class Student
{
public string UserName {
get; set; }
public string ClassName {
get; set; }
public string Address {
get; set; }
}
List<Student> students = new List<Student>();
students.Add(new Student() {
UserName = "小王", ClassName = "高二三班", Address = "广州市" });
students.Add(new Student() {
UserName = "小李", ClassName = "高三六班", Address = "清远市" });
students.Add(new Student() {
UserName = "小张", ClassName = "高一一班", Address = "深圳市" });
students.Add(new Student() {
UserName = "小黑", ClassName = "高一三班", Address = "赣州市" });
gd.ItemsSource = students;
ItemTemplate
Used to bind control content, as follows
<Window.Resources>
<DataTemplate x:Key="comTemplate">
<StackPanel Orientation="Horizontal" Margin="5,0">
<Border Width="10" Height="10" Background="{Binding Code}"/>
<TextBlock Text="{Binding Code}" Margin="5,0"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<ComboBox Name="cob" Width="120" Height="30" ItemTemplate="{StaticResource comTemplate}"/>
<ListBox Name="lib" Width="120" Height="100" Margin="5,0" ItemTemplate="{StaticResource comTemplate}"/>
</StackPanel>
</Grid>
Bind data
public class Color
{
public string? Code {
get; set; }
}
List<Color> ColorList = new List<Color>();
ColorList.Add(new Color() {
Code = "#FF8C00" });
ColorList.Add(new Color() {
Code = "#FF7F50" });
ColorList.Add(new Color() {
Code = "#FF6EB4" });
ColorList.Add(new Color() {
Code = "#FF4500" });
ColorList.Add(new Color() {
Code = "#FF3030" });
ColorList.Add(new Color() {
Code = "#CD5B45" });
cob.ItemsSource = ColorList;
lib.ItemsSource = ColorList;
ContentTemplate
It's rarely used, so I won't mention it anymore.
binding
Front-end display and back-end data association
Bind controls
By giving the control a name, and then binding the text value to the value of the slider control above based on the name.
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Slider Name="slider" Width="200" />
<TextBlock Text="{Binding ElementName=slider, Path=Value}" HorizontalAlignment="Center" />
</StackPanel>
binding mode
Set it up as follows
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Slider Name="slider" Width="200" />
<TextBox Width="200" Text="{Binding ElementName=slider, Path=Value, Mode=OneWay}" HorizontalAlignment="Center" />
</StackPanel>
Common patterns
OneWay : 单向绑定,绑定对象会决定自己
TwoWay : 双向绑定,下面输入后tab即可显示
OneTime : 只绑定第一次的值,这里直接绑定启动的值了
OneWayToSource : 与OneTime一样,对象相反
Default : 默认单项或双向
Bind data
Source
<Window.Resources>
<TextBox x:Key="txt1">ABC</TextBox>
</Window.Resources>
<Grid>
<TextBox Text="{Binding Source={StaticResource txt1}, Path=Text}" />
</Grid>
RelativeSource
View data for related tags
<StackPanel Width="20">
<StackPanel Width="60">
<TextBlock Text="{Binding Path=Width,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type StackPanel}}}" />
</StackPanel>
</StackPanel>
DataContext
Binding to code data
<Grid>
<DataGrid Grid.Row="1" ItemsSource="{Binding Students}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" Header="名称" />
<DataGridTextColumn Binding="{Binding Age}" Header="年龄" />
<DataGridTextColumn Binding="{Binding Sex}" Header="性别" />
</DataGrid.Columns>
</DataGrid>
</Grid>
binding
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
PageModel page = new PageModel();
page.Students = new List<Student>();
page.Students.Add(new Student() {
Name = "张三", Age = "18", Sex = "男" });
page.Students.Add(new Student() {
Name = "李四", Age = "19", Sex = "男" });
page.Students.Add(new Student() {
Name = "王二", Age = "20", Sex = "女" });
this.DataContext = page;
}
}
public class PageModel
{
public List<Student> ?Students {
get; set; }
}
public class Student
{
public string? Name {
get; set; }
public string? Age {
get; set; }
public string? Sex {
get; set; }
}
MVVM
High returns when developing large-scale projects
Our page design xaml is separated from our data. Using the framework, the two can be completely separated.
Set the interface and binding (data, function (function parameters)) in MainWindow.xaml
Implement data processing and provide function interfaces in MainViewModel.cs (replace the native settings in MainWindow.xaml.cs)
Separate the front-end and back-end work and concentrate on one logic
There are many MVVM frameworks, here we use prism
Actual combat
Divide the page into areas and use areas to facilitate settings
Installation framework: Project->Manage NuGet packages->Prism.DryIoc (Prism Dry Inversion of Control)
NuGet (pronounced "New Get") is a package management system for the .NET platform
Using Prism
Operate App.xaml
cs
Modify inheritance and override methods
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
//初始页
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//用于注册要实现的页面
}
}
xaml
Add namespace prism and remove StartupUri
<prism:PrismApplication x:Class="WPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF"
xmlns:prism ="http://prismlibrary.com/">
<Application.Resources>
</Application.Resources>
</prism:PrismApplication>
Project template
Extensions->Manage Extensions->Prism Template Pack->Then create a new project for the template, and the content using the framework above will be automatically configured.
The framework automatically generates two folders:
Views are used to store our interface
ViewModels to store our instructions
As long as they are placed in these two folders, they will be automatically associated, so there is no need to specify them.
Then we need to understand regions. In the framework, the interface is controlled through regions.
MainWindow.xaml
Define regions in code
<ContentControl prism:RegionManager.RegionName="ContentRegion" Grid.ColumnSpan="2" />
If you need to display it, MainWindowViewModel.cs
register the area in,
The interface ViewA will be displayed below.
public class MainWindowViewModel : BindableBase
{
private IRegionManager regionManager;
public MainWindowViewModel(IRegionManager regionManager)
{
this.regionManager = regionManager;
regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));
}
}
module
Create->Module
module ModuleAModule.cs
files
public class ModuleAModule : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
var regionManager = containerProvider.Resolve<IRegionManager>();
regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
}
}
Then the App of the main program
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
moduleCatalog.AddModule<ModuleA.ModuleAModule>();
}
}
MAUI
Need to download .NET Multi_platform App UI development
New->.NET MAUI->.net6.0->Run
Because it is cross-platform, there is no way to render it in real time like WPF. You have to run it yourself to see the effect, but it is really convenient.
Because it is cross-platform, development costs are low and running costs are high.
Sample program calculator source code
Project structure
- App is the entry point of MAUI applications. They define an App class, which inherits from the Application class; App.xaml uses
XAML language to declare the properties and resources of the App class, such as theme color, font size, etc.; App.xaml.cs uses C# language
is used to write the logic of the App class, such as initializing the application, setting the main window, handling life cycle events, etc. - AppShell is the navigation framework of MAUI applications. They define an AppShell class, which inherits from the Shell class;
AppShell.xaml uses XAML language to declare the content and structure of the AppShell class, such as navigation menus, tabs, flyout
pages, etc.; AppShell.xaml .cs is the logic of the AppShell class written in C# language, such as registering routes, processing navigation events
, etc. - MainPage is the main page of the MAUI application. They define a MainPage class, which inherits from the ContentPage class;
MainPage.xaml uses XAML language to declare the user interface of the MainPage class, such as controls, layout, styles, etc.;
MainPage.xaml.cs uses C# Language to write the logic of the MainPage class, such as event processing, data binding, page life
cycle, etc. - MauiProgram.cs is the cross-platform entry point of the application, which is used to configure and start the application. The template startup code points to
the App class defined in the App.xaml file.
Android environment
Use virtual machine or real machine
- An emulator is a virtual device that can simulate devices of different platforms on your development machine, such as Android phones or iOS phones. For configuration methods, please refer to: Managing Virtual Devices
- A real machine is a physical device that can be connected to your development machine, such as an Android phone or iOS phone, via USB or wirelessly. For configuration methods, please refer to: Setting Up Devices for Development
Safety
Be careful with all inputs (regular matching) to prevent random inputs from crashing the program, that is, to improve robustness
As entered in the calculator1***************1*