WPF Imitation NetEase Cloud Construction Notes (2): Komponentenentwicklung

Vorwort

Dieses Mal erklären wir den Komponentenentwicklungsprozess von WPF. Die Komponentenentwicklung ist eine Methode, die die Schwierigkeit unserer Seitenentwicklung erheblich reduzieren und die Codekopplung reduzieren kann. Dadurch können wir jede WPF-Schnittstelle zerlegen. Da ich Vue geschrieben habe, werde ich WPF gemäß der Logik von Vue in Komponenten entwickeln.

Column- und Gitee-Repository

WPF imitiert das NetEase Cloud Gitee Warehouse

WPF imitiert die NetEase Cloud CSDN-Blogspalte

Abhängigkeitseigenschaften

Um die Leistung zu verbessern, beschränkt WPF die Verwendung von Binding. Eigenschaften müssen im Voraus als abhängige Eigenschaften oder zusätzliche Eigenschaften registriert werden, um die Bindungssyntax verwenden zu können. Der Grund dafür ist, dass jedes bindbare Attribut Speicherplatz im Speicher freigeben muss. WPF kann standardmäßig nicht gebunden werden und muss aktiv deklariert werden.

Aus diesem Grund ist der Speicheraufwand von Elelctron, Fullter usw. so groß, weil sie auch Speicherplatz einrichten, der möglicherweise nutzlos ist.

Blog Park Detaillierte Erläuterung der WPF-Abhängigkeitseigenschaften

Station B Kälteeinbruch im Oktober Das Konzept und die Verwendung abhängiger Eigenschaften und angehängter Eigenschaften in WPF

Bilibili Microsoft-Reihe technischer Tutorials Detaillierte Erläuterung der WPF-Abhängigkeitseigenschaften

Praktischer Kampf: Verkleinern, Vollbild, Schließen-Taste

Hier erkläre ich den Unterschied zwischen Window und UserControl. Window ist das gesamte Fenster und UserControl ist das Steuerelement. Fenster ist für einige Methoden des Fensters verantwortlich, z. B. Ziehen, Vergrößern und Verkleinern. Da wir Komponenten entwickeln, müssen wir diesen Teil des Hauptfensters an die Unterkomponenten übergeben.

Kapselung von Abhängigkeitsattributoperationen

Werfen wir zunächst einen Blick auf meinen zusammenfassenden Blog.

Die WPF-Benutzersteuerung basiert auf der Zuweisung von Eigenschaften

Das Hauptfenster übergibt dies selbst an das TitleView-Titelsteuerelement

Da wir View und ViewModel entwickeln, haben alle Views nur die Funktion, Parameter zu übergeben und Abhängigkeitseigenschaften offenzulegen. Das eigentliche Geschäft wird von ViewModel erledigt.
Die Richtung, in die wir gehen, ist also

MainWindow
MainWindowViewModel
TitleView的MainWindow依赖属性
TitleViewModel的MainWindow

Haupt code

MainWindow.xmal


<Window x:Class="BlankApp1.Views.MainWindow"
        ......>
    <!--需要主动设置名称,不然会Binding错误-->
    <Window.DataContext>
        <ViewModels:MainWindowViewModel x:Name="MainWindowViewModel" />
    </Window.DataContext>
    <DockPanel LastChildFill="True">
		<!--其它代码-->
        <Grid DockPanel.Dock="Top"
              MouseLeftButtonDown="Grid_MouseLeftButtonDown"
              Height="auto">
            <!--手动指定DataContext-->
            <Views:TitleView  MainWindow="{Binding MainWindow, ElementName=MainWindowViewModel}"  />
        </Grid>

    </DockPanel>
</Window>

MainWindow.cs

    public partial class MainWindow : Window
    {
    
    

        public MainWindowViewModel ViewModel {
    
     get; set; }

        public MainWindow()
        {
    
    
            InitializeComponent();
            //重定向ViewModel
            ViewModel = (MainWindowViewModel)DataContext;
            ViewModel.MainWindow = this;
        }
    }

Kapselung der Abhängigkeitseigenschaftsmethode

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace BlankApp1.Utils
{
    
    
    public class MyWpfExtension<View> where View : class
    {
    
    
        
        
        /// <summary>
        /// 简化依赖注入代码
        /// </summary>
        /// <typeparam name="View"></typeparam>
        /// <typeparam name="Value"></typeparam>
        /// <param name="name"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public DependencyProperty DependencyPropertySet<Value>(string name, Action<View, Value> action)
        {
    
    
            var res = DependencyProperty.Register(name, typeof(Value), typeof(View), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                new PropertyChangedCallback((item, res) =>
                {
    
    
                    var model = item as View;
                    var value = (Value)res.NewValue;
                    if (model != null)
                    {
    
    
                        action(model, value);
                    }
                    else
                    {
    
    
                        throw new Exception("model value is null");
                    }
                })));
            return res;
        }

    }
}

TitleView.cs


namespace BlankApp1.Views
{
    
    
    /// <summary>
    /// TitleView.xaml 的交互逻辑
    /// </summary>
    public partial class TitleView : UserControl
    {
    
    

        //这个只是为了代码提示,不涉及逻辑
        public MainWindow MainWindow {
    
     get; set; }

        //初始化依赖属性构造器
        public  static readonly MyWpfExtension<TitleView> MyWpfExtension = new MyWpfExtension<TitleView>();

        //这个是简化后的依赖属性
        public static readonly DependencyProperty MainWindowProperty = 
            MyWpfExtension.DependencyPropertySet<MainWindow>("MainWindow", (view, value) =>
        {
    
    
        	//通过依赖属性来获取MainWindow的对象
            view.TitileViewModel.MainWindow = value;
        });

        /// <summary>
        /// DataContext的数据
        /// </summary>
        public TitileViewModel TitileViewModel {
    
     get; set; }

        public TitleView()
        {
    
    
            InitializeComponent();
            //拿到DataContext数据重定向
            TitileViewModel = (TitileViewModel)DataContext;
        }
    }
}

TitleViewModel

using BlankApp1.Models;
using BlankApp1.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace BlankApp1.ViewModels
{
    
    
    public partial class TitileViewModel:ObservableObject
    {
    
    

        public RelayCommand CloseWindow {
    
     get; set; }

        public RelayCommand MaxOrNormalWindow {
    
     get; set; }

        public RelayCommand MiniWindow {
    
     get; set; }

        public MainWindow MainWindow {
    
     get; set; }


        public TitileViewModel() {
    
    
			//.......其它代码
            CloseWindow = new RelayCommand(() => {
    
    
                MainWindow.Close();
                Debug.WriteLine("关闭窗口");
            });

            MaxOrNormalWindow = new RelayCommand(() => {
    
    
                if(MainWindow.WindowState == WindowState.Normal)
                {
    
    
                    MainWindow.WindowState = WindowState.Maximized;
                    MainWindow.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
					MainWindow.MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
                }
                else
                {
    
    
                    MainWindow.WindowState = WindowState.Normal;
                }
                Debug.WriteLine("最大化或正常窗口");
            });
            MiniWindow = new RelayCommand(() => {
    
    
                MainWindow.WindowState = WindowState.Minimized;
                Debug.WriteLine("缩小窗口");
            });
        }

    }
}

TitleViewModel

Es ist nur ein verbindliches Schaltflächenereignis, ich werde es nicht loslassen
Den detaillierten Code finden Sie in meiner Gitee-Lageradresse

WPF imitiert das NetEase Cloud Gitee Warehouse

Wirkung erzielen

Fügen Sie hier eine Bildbeschreibung ein

Supongo que te gusta

Origin blog.csdn.net/qq_44695769/article/details/134899341
Recomendado
Clasificación