"In-depth and simple WPF" study notes

related resources

"Introduction to WPF in Simple" series of high-definition video tutorials | Lecturer: Liu Tiemeng

Download the full version of wpf pdf version in simple terms,
Mr. Liu Tiemeng's B station number. but only recent video material
insert image description here

foreword

WPF is a very advanced technical framework, even though it was developed in 2007 and officially released in 2010. The MVVM inside, the business code and the interface code are completely separated, and the idea of ​​low coupling and high cohesion has always affected the later front-end development. For example, Vue is inherited from MVVM.

The situation of WPF in the domestic job market is not ideal. The reason is that the desktop software has declined, and the functions have gradually shifted from the PC side to the WEB side. I can solve it with a web page, why do I need a client? The promotion of WPF technology is also a problem. Because of the rise of the traditional Internet, Java has been raised to a very high level. Java has a lot of wheels, the ecology is particularly good, and there are many people who learn it.

So I think, don't think that you can find a good job after learning WPF. .NET engineers still have to switch to the full stack, both front-end and back-end. I currently think the simplest full-stack technology stack is Vue+uniapp+WPF+webApi+.NET core. Database: Sql server sqlite Mysql. In fact, it is best to learn Unity 2d+Unity 3d +C4D. This is the complete full stack. Basically a simple small project you can solve.

My template for this year is to learn WPF+Unity 2d+C4D modeling. The logic of my learning has always been from low to high, that is, to learn how to use tools first, and then to delve into advanced things. After learning this part, I will start learning linux and python next year.

C# and JAVA are competing with each other, and I don't have the energy to learn Java for the time being. I'll talk about it when I need it

Although a bit off topic, back toEasy to understand WPF, Teacher Liu Tiemeng is still very fierce, and the explanation is very good. Unlike other classes, I will talk about the control properties for a few hours first. It starts directly from the principle, from the bottom layer to the application, which is very clear.

WPF study notes

Video data address

"Introduction to WPF in Simple" series of high-definition video tutorials | Lecturer: Liu Tiemeng

Environment configuration

  • .NET Core 6.0
  • WPF

insert image description here

WPF basics: how a WPF program is started

A simple WPF program we created.
insert image description here

How are xmal files and cs files connected

In order to separate pages and services, WPF forces us to only write pages in xmal and write services in cs files. This forced separation is to reduce coupling. If some students have tried to maintain the JQuery project, they will know how painful it is that the business and the page are not separated. A function contains page logic and business logic, so when making changes in the later stage, you must fully understand how the entire function works, and if you delete a variable at will, you will report an error directly.

Let's take App.xmal and App.xaml.cs as an example
insert image description here
insert image description here

insert image description here

How to determine the splash page

insert image description here

How does an xmal file refer to other files

insert image description here

how to cite

insert image description here
insert image description here

How WPF creates elements and changes elements

WPF performs a high degree of page and business segmentation, and then maps the corresponding pages and files through compilation. All our element creation and simple interaction events happen in xmal.

WPF element creation and simple attribute assignment

Take a simple button as an example

Create controls in layout elements.

<Grid>
    <Button  Content="Show Msg!"//显示的文字
             Click="Button_Click"//点击事件
             Width="100"//宽度
             Height="30" />//高度
</Grid>

What is wrapped by <> is a label, and the <> is followed by an attribute. In the above example, Button is the label, and Grid is also the label. Content, Click, Width, and Height are all attributes.
achieve effect

insert image description here

WPF tree interface

WPF's xmal is very similar to html, both are markup languages

insert image description here
insert image description here
insert image description here
This tree hierarchy is the hierarchy of WPF.

If you want to know more about it, you can read my previous article.
How WPF Views Page Elements in Real Time How to Use the Real-time Visual Tree

Xmal attribute assignment

There are three methods of attribute assignment in Xmal.

  • Inline label: the default assignment method
  • Property Label: String Input Conversion Data Type
  • extension tab

Why multiple attribute assignments

Let's look at the simplest Button button

<Grid>
    <Button  Content="Show Msg!"//字符串标签
             Click="Button_Click"
             Width="100"//属性标签
             Height="30" />
</Grid>

We can see that the values ​​we assign are all strings. Like Content, it must be a string, but Width and Height, the attribute value should be a number, but what we input is also a string. Just to clarify: we can convert the copied string.

attribute conversion

The purpose of attribute conversion is for us to generate some complex information through tag attributes. For example, Height = "100". Height assigns a string, which must be converted into a number.

We create a new Person class

MainWindow.cs

namespace WpfLearnTest
{
    
    
    public partial class MainWindow : Window
    {
    
    
        public MainWindow()
        {
    
    
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)//按钮事件
        {
    
    
        	///找到资源字典中名字为person的类
            Person _model = (Person)this.FindResource("person");
            MessageBox.Show(_model.Name);
        }
    }

    public class Person
    {
    
    
        public string Name {
    
     get; set; }

        public Person Chil {
    
     get; set; }

    }
}

MainWindow.xmal

<Window x:Class="WpfLearnTest.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:WpfLearnTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
     
    
    <Window.Resources>
        <local:Person x:Key="person" Name="小王" />//声明Person类
    </Window.Resources>
    <Grid>
        <Button  Content="Show Msg!"
                 Click="Button_Click"//添加点击按钮
                 Width="100"
                 Height="30" />
    </Grid>
</Window>

achieve results

insert image description here
The reason it works is because the Name of our Person class is a string, but what if it's not a string?
insert image description here

insert image description here

We can see that Child reports an error. Strings cannot be directly transferred to the Person class.

Solution
	///引入属性转换
    [TypeConverterAttribute(typeof(NameToPersonTypeConverter))]
    public class Person
    {
    
    
        public string Name {
    
     get; set; }

        public Person Child {
    
     get; set; }

    }
    /// <summary>
    /// 添加属性转换
    /// </summary>
    public class NameToPersonTypeConverter : TypeConverter
    {
    
    
        public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
        {
    
    
            string name = value.ToString();
            Person child = new Person();

            child.Name = name;
            return child;
        }
    }

Effect:

insert image description here
insert image description here
The operation result is successful!

insert image description here

property label

issues that need resolving.

insert image description here

On the web page, how is it implemented in Html+css?

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>一个简单的网页</title>
	</head>
	<body>
        <div>
            <button style="width: 100px;height: 30px;">
                <div style="height: 10px;min-width: 10px;border: 1px solid red;display: inline-block;"></div>
            </button>
        </div>

	</body>
</html>

insert image description here
Nesting can also be used in xmal

<Window x:Class="WpfLearnTest.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:WpfLearnTest"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800">


    <Grid>
        <Button 
                Width="100"
                Height="30">
            <Rectangle Width="20"
                       Height="20"
                       Stroke="DarkGreen"
                       Fill="LawnGreen" />

        </Button>
    </Grid>
</Window>

insert image description here
But xmal supports us to useproperty labelfill in

        <Button Click="Button_Click"
                Width="100"
                Height="30">
            <Button.Content>//属性标签,对应button的content值
                <Rectangle Width="20"
                           Height="20"
                           Stroke="DarkGreen"
                           Fill="LawnGreen" />
            </Button.Content>
        </Button>

The effect achieved is the same
insert image description here

So what is the use of nesting an attribute tag?

The conclusion is that there is no difference in this case.

In the real-time visual tree there is no difference
insert image description here

Advantages and Disadvantages of Attribute Tags

We now have a need
insert image description here

        <Rectangle Width="200"
                   Height="160"
                   Stroke="Blue"
                   Fill="LightBlue" />

Let's see how html+css solves it.
The web page is separated with html+css+JS. Only let html declare elements and let css modify styles. In principle, JS does not add or delete html elements during use (although DOM operations can be implemented, but this will increase coupling and easily form shit mountain codes), but through css display: none. To display or not display the page style.

声明页面元素
修改Html样式
动态html对应的CSS
实现业务逻辑
原则上不能直接操控Html
的元素生成
原则上不能修改CSS的样式内容
用户页面
Html
CSS
JS
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>一个简单的网页</title>
</head>
<body>
    <div id="box">
    </div>
</body>
</html>
<style type="text/css">
    #box {
      
      
        height: 200px;
        background-color: red;
        background-image: linear-gradient(to bottom right, red, blue);
    }
</style>

achieve effect
insert image description here

Disadvantages of attribute tags

Let's see how to write WPF to achieve the above effect?

<Rectangle Width="200"
                   Height="160"
                   Stroke="Blue">
            <Rectangle.Fill>
                <LinearGradientBrush>
                    <LinearGradientBrush.StartPoint>
                        <Point  X="0"
                                Y="0" />
                    </LinearGradientBrush.StartPoint>
                    <LinearGradientBrush.EndPoint>
                        <Point X="1"
                               Y="1" />
                    </LinearGradientBrush.EndPoint>
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.2"
                                      Color="LightBlue" />
                        <GradientStop Offset="0.7"
                                      Color="DarkBlue" />
                        <GradientStop Offset="1.0"
                                      Color="LightBlue" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

insert image description here

We can see that it is just a simple gradient effect, so it is very troublesome to write

Of course, we can use inline tags to optimize

<Rectangle Width="200"
                   Height="160"
                   Stroke="Blue">
            <Rectangle.Fill>
                <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">//使用行内标签来对代码进行优化
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.2"
                                      Color="LightBlue" />
                        <GradientStop Offset="0.7"
                                      Color="DarkBlue" />
                        <GradientStop Offset="1.0"
                                      Color="LightBlue" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

We can use resource dictionaries to optimize

 <Window.Resources>
        <Style x:Key="MyButton"
               TargetType="Button">
            <Style.Setters>
                <Setter Property="Content"
                        Value="" />
            </Style.Setters>
        </Style>
        <Style x:Key="MyRectFill" TargetType="Rectangle">
            <Style.Setters>
                <Setter Property="Fill" >
                    <Setter.Value>
                        <LinearGradientBrush StartPoint="0,0"
                                             EndPoint="1,1">
                            <GradientStop Offset="0.2"
                                          Color="LightBlue" />
                            <GradientStop Offset="0.7"
                                          Color="DarkBlue" />
                            <GradientStop Offset="1.0"
                                          Color="LightBlue" />
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
            </Style.Setters>
        </Style>
    </Window.Resources>
    <Grid>
        <Rectangle Width="200"
                   Height="160"
                   Stroke="Blue" Style="{ 
        StaticResource MyRectFill}" >
        </Rectangle>
    </Grid>

We ensure the simplification of page elements, but due to the operation of WPF, Window.Resources can only be placed before page elements. And since C# and Xmal are strongly defined languages, it is necessary to declare the element content when writing.

What can be solved by 5 lines in CSS can be solved by 10 lines in Xmal.

extension tab

In the code we just wrote

        <Rectangle Width="200"
                   Height="160"
                   Stroke="Blue" Style="{ 
        StaticResource MyRectFill}" >//这个就是扩展标签
        </Rectangle>

The extension tag uses the form of {} to include the attribute value in it. At this time, what we input is not a string, but an attribute object. If students have learnedVueYou can see that this is similar toVueThe difference expression { {value}}.

Tag extensions generally work with attribute binding, and I will explain how to use attribute binding later. This is the focus of WPF.

WPF Property Binding

Assignment of page elements to each other

I said earlier that content relationships in WPF are as follows

负责所有的页面元素
样式和简单的用户交互
C#
复杂的交互逻辑
业务逻辑
Xmal
负责Style管理和资源管理
windows.Resource
Style
负责样式管理,触发器管理
xmal元素
负责声明元素
用户页面
数据交互和触发事件回调

In xmal, elements can be communicated, but not on the Web side. The Web needs to modify data through JS event triggers. This is event-driven. The event-driven type believes that all page interactions are triggered by events, and the communication between two page elements must have an intermediate event.

修改对应元素值
页面A数据修改
触发JS函数
B元素修改

In Xmal, it is data-driven, or it can be regarded as an anonymous event. That is, I don't need to declare an event, I just give him the value directly

A被修改属性
xmal元素A
xmal元素B联动

xmal code

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="24" />
            <RowDefinition Height="4" />
            <RowDefinition Height="24" />
        </Grid.RowDefinitions>
        <TextBox  x:Name="tb"
                  Text="{Binding ElementName=sld,Path=Value}" />
        <Slider  x:Name="sld"
                 Grid.Row="2"
                 Value="50"
                 Maximum="100"
                 Minimum="0" />
    </Grid>

insert image description here

WPF data binding will be described in detail later in the Prism framework.

WPF componentization

Componentization means encapsulating a reusable interface into a component. There are 4 classes in WPF

insert image description here

  • window: a window. Windows cannot be nested
  • Page: It is rarely used, and I don’t know what it does, it seems to be a web page.
  • User Control: Set on top of the window. for abstracting components
  • Resource dictionary: used to manage WPF resources, such as styles and controls.

We create a new WPF resource class

insert image description here
insert image description here
New Project

Then add the following code

UserControl1.xmal

<UserControl x:Class="ControlLibrary.UserControl1"
             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:ControlLibrary"
             mc:Ignorable="d"
             d:DesignHeight="160"
             d:DesignWidth="240"
             Background="LightBlue">
    <Canvas>
        <TextBox Canvas.Left="110"
                 TextWrapping="Wrap"
                 x:Name="textBox1"
                 Canvas.Top="10"
                 Width="120"
                 HorizontalAlignment="Left"
                 VerticalAlignment="Center"/>
        <TextBox Canvas.Left="110"
                 TextWrapping="Wrap"
                 x:Name="textBox3"
                 Canvas.Top="105"
                 Width="120"
                 HorizontalAlignment="Left"
                 VerticalAlignment="Top" />
        <TextBox Canvas.Left="110"
                 TextWrapping="Wrap"
                 x:Name="textBox2"
                 Canvas.Top="63"
                 Width="120"
                 HorizontalAlignment="Left"
                 VerticalAlignment="Center" />
        <TextBlock TextWrapping="Wrap"
                   Canvas.Top="10"
                   Canvas.Left="10"><Run Language="zh-cn"
                                         Text="num1" /></TextBlock>
        <TextBlock TextWrapping="Wrap"
                   Canvas.Top="63"
                   Canvas.Left="10"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Top"><Run Text="num" /><Run Language="zh-cn"
                                                                  Text="2" /></TextBlock>
        <TextBlock TextWrapping="Wrap"
                   Canvas.Top="107"
                   Canvas.Left="10"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Top"><Run Language="zh-cn"
                                                Text="总计" /></TextBlock>
        <Button Content="计算"
                Canvas.Left="126"
                Canvas.Top="136"
                HorizontalAlignment="Left"
                VerticalAlignment="Center"
                Width="88"
                Click="Button_Click" />
    </Canvas>
</UserControl>

UserControl.xmal.cs

using System;
......

namespace ControlLibrary
{
    
    
    /// <summary>
    /// UserControl1.xaml 的交互逻辑
    /// </summary>
    public partial class UserControl1 : UserControl
    {
    
    
        public UserControl1()
        {
    
    
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
    
    
                        this.textBox3.Text = ( int.Parse(this.textBox1.Text) + int.Parse(this.textBox2.Text) ).ToString();

        }
    }
}

insert image description here

and then add a reference to it

insert image description here
Regenerate every project
insert image description here

referenced in the main function

<Window x:Class="WpfLearnTest.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:WpfLearnTest"
        xmlns:sys="clr-namespace:System.Security.Claims;assembly=mscorlib"
        xmlns:controls="clr-namespace:ControlLibrary;assembly=ControlLibrary"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <controls:UserControl1 Grid.Row="0"
                               Grid.Column="0" />
        <controls:UserControl1 Grid.Row="1"
                               Grid.Column="1" />
        <controls:UserControl1 Grid.Row="1"
                               Grid.Column="0" />

        <controls:UserControl1 Grid.Row="0"
                               Grid.Column="1" />
    </Grid>
</Window>

insert image description here

use result
insert image description here

It can be imported directly, and the code of the user control can be executed (the total result is num1+num2).

Guess you like

Origin blog.csdn.net/qq_44695769/article/details/131348652