最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解WPF中MVVM架構中的多種數據綁定方式

 更新時間:2025年09月26日 09:41:41   作者:苦蕎米  
這篇文章主要為大家詳細介紹了WPF中MVVM架構中的多種數據綁定方式,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

WPF基礎框架

通過繼承接口INotifyPropertyChangedICommand 來實現。

數據綁定部分

INotifyPropertyChanged原代碼如下,WPF框架會自動注冊DataContext對象中的PropertyChanged事件(若事件存在)。然后根據該事件修改前端屬性。

namespace System.ComponentModel
{
    // Notifies clients that a property value has changed.
    public interface INotifyPropertyChanged
    {
        // Occurs when a property value changes.
        event PropertyChangedEventHandler? PropertyChanged;
    }
}

注意:INotifyPropertyChanged接口并非是強制要求的,當不需要通過設置屬性自動修改頁面數據時,也就是不需要執(zhí)行set方法時,不需要繼承該接口。若使用了通知集合ObservableCollection,也是不需要專門通過事件通知頁面的。

public class NativeViewModel : INotifyPropertyChanged
{
    private string _name;

    public string Name
    {
        get => _name;
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged();
            }
        }
    }
    protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
<StackPanel>
    <TextBox Text="{Binding Name}" />
</StackPanel>

數據綁定中的命令綁定

ICommand 原代碼如下,可以看到其中有按鈕操作常用的幾種屬性:是否可用、可用性變化、觸發(fā)事件。與前端通過Click屬性指定事件相比:一個是前端指定要執(zhí)行的邏輯,一個是由vm來確定最終的執(zhí)行邏輯,相當于是反轉了控制方??梢愿鶕枰褂?、并非強制要求。

#nullable enable

using System.ComponentModel;
using System.Windows.Markup;

namespace System.Windows.Input
{
    //
    // 摘要:
    //     Defines a command.
    [TypeConverter("System.Windows.Input.CommandConverter, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null")]
    [ValueSerializer("System.Windows.Input.CommandValueSerializer, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null")]
    public interface ICommand
    {
        //
        // 摘要:
        //     Occurs when changes occur that affect whether or not the command should execute.
        event EventHandler? CanExecuteChanged;

        //
        // 摘要:
        //     Defines the method that determines whether the command can execute in its current
        //     state.
        //
        // 參數:
        //   parameter:
        //     Data used by the command. If the command does not require data to be passed,
        //     this object can be set to null.
        //
        // 返回結果:
        //     true if this command can be executed; otherwise, false.
        bool CanExecute(object? parameter);
        //
        // 摘要:
        //     Defines the method to be called when the command is invoked.
        //
        // 參數:
        //   parameter:
        //     Data used by the command. If the command does not require data to be passed,
        //     this object can be set to null.
        void Execute(object? parameter);
    }
}

對于ICommand屬性,推薦使用方式是不要讓其觸發(fā)PropertyChanged,不應該被動態(tài)設置,而應該初始定好。不過如果使用場景確實需要,應該也是能生效的。

public class NativeViewModel
{
    public ICommand GreetCommand { get; }

    public NativeViewModel()
    {
        // 使用自定義的 RelayCommand 需要自己實現
        GreetCommand = new RelayCommand();
    }
}

// 需要實現的簡單命令類
public class RelayCommand : ICommand
{
    // 略
}
<StackPanel>
    <Button Content="Say Hello" Command="{Binding GreetCommand}" />
</StackPanel>

CommunityToolkit.Mvvm 方式

CommunityToolkit.Mvvm 利用 C# 的源碼生成器,在編譯時自動生成INotifyPropertyChangedICommand的樣板代碼。需要nuget包CommunityToolkit.Mvvm。

其僅在vm上有區(qū)別,在實際綁定方式上沒有區(qū)別。

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

// 3. 使用 [ObservableObject] 特性或繼承 ObservableObject
[ObservableObject]
public partial class ToolkitViewModel
{
    // 4. 使用 [ObservableProperty] 標記字段,自動生成名為 "Name" 的屬性
    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(GreetCommand))] // 當 Name 改變時,通知 GreetCommand 重新驗證
    private string _name;

    [ObservableProperty]
    private string _greeting;

    // 5. 使用 [RelayCommand] 自動生成名為 GreetCommand 的 ICommand 屬性
    [RelayCommand(CanExecute = nameof(CanGreet))]
    private void Greet()
    {
        Greeting = $"Hello from Toolkit, {Name}!";
    }

    private bool CanGreet() => !string.IsNullOrWhiteSpace(Name);
}

ReactiveUI

ReactiveUI 將響應式編程理念引入 MVVM,核心是使用ReactiveObjectWhenAnyValue等來聲明數據流和反應關系。需要nuget包ReactiveUI.WPF。

其僅在vm上有區(qū)別,在實際綁定方式上沒有區(qū)別。

using ReactiveUI;
using System.Reactive.Linq;

// 6. 繼承 ReactiveObject
public class ReactiveViewModel : ReactiveObject
{
    // 7. 使用 [Reactive] 特性或 WhenAnyValue
    private string _name;
    public string Name
    {
        get => _name;
        set => this.RaiseAndSetIfChanged(ref _name, value);
    }

    private readonly ObservableAsPropertyHelper<string> _greeting;
    public string Greeting => _greeting.Value;

    // 8. 使用 ReactiveCommand 創(chuàng)建命令
    public ReactiveCommand<Unit, Unit> GreetCommand { get; }

    public ReactiveViewModel()
    {
        // 判斷命令何時可執(zhí)行:當 Name 不為空時
        var canGreet = this.WhenAnyValue(x => x.Name, name => !string.IsNullOrWhiteSpace(name));

        // 創(chuàng)建命令
        GreetCommand = ReactiveCommand.CreateFromTask(
            execute: async () => { /* 可以執(zhí)行異步操作 */ return $"Hello from ReactiveUI, {Name}!"; },
            canExecute: canGreet // 綁定可執(zhí)行條件
        );

        // 9. 將命令的執(zhí)行結果(一個IObservable<string>)訂閱到 Greeting 屬性
        _greeting = GreetCommand.ToProperty(this, x => x.Greeting, initialValue: "Waiting...");

        // 另一種更直接的寫法(不通過命令結果):
        // GreetCommand = ReactiveCommand.Create(() => { Greeting = $"Hello from ReactiveUI, {Name}!"; }, canGreet);
        // 但上面那種方式展示了將 IObservable 流轉換為屬性的強大能力。
    }
}

到此這篇關于詳解WPF中MVVM架構中的多種數據綁定方式的文章就介紹到這了,更多相關WPF MVVM架構的數據綁定內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • c#:CTS類型系統(tǒng)

    c#:CTS類型系統(tǒng)

    CTS通用類型系統(tǒng),是.Net中一套定義類型的規(guī)則。我們要掌握c#開發(fā),首先要建立這個類型概念,只有知道c#的元素是什么類型,才能進行相關的分析和選材。
    2012-12-12
  • C#零基礎開發(fā)中最重要的概念總結

    C#零基礎開發(fā)中最重要的概念總結

    這篇文章主要為大家詳細介紹了C#零基礎開發(fā)中最重要的一些概念,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,需要的可以參考一下
    2023-02-02
  • C#中常使用進度條的代碼

    C#中常使用進度條的代碼

    C#中常使用進度條的代碼...
    2007-03-03
  • 基于C#實現獲取本地磁盤目錄

    基于C#實現獲取本地磁盤目錄

    這篇文章主要為大家詳細介紹了如何利用C#實現獲取本地磁盤目錄的功能,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • C#從foreach語句中枚舉元素看數組詳解

    C#從foreach語句中枚舉元素看數組詳解

    這篇文章主要給大家介紹了關于C#從foreach語句中枚舉元素看數組的相關資料,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • WPF中引入WindowsForms控件的方法

    WPF中引入WindowsForms控件的方法

    這篇文章主要介紹了WPF中引入WindowsForms控件的方法,結合實例形式分析了在WPF中調用Windows Forms控件的具體步驟與相關實現技巧,需要的朋友可以參考下
    2016-07-07
  • C#凈化版WebApi框架的實現

    C#凈化版WebApi框架的實現

    這篇文章主要介紹了C#凈化版WebApi框架的實現,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • C#特性-對象集合初始化器介紹

    C#特性-對象集合初始化器介紹

    在寫一些實體類的時候,我們往往在寫構造方法的時候思考很長時間,除了一個無參構造器外還在想需要寫幾個構造器呢?哪些參數是需要初始化的?,F在你再也不需要為這事煩惱了
    2014-12-12
  • c#斐波那契數列(Fibonacci)(遞歸,非遞歸)實現代碼

    c#斐波那契數列(Fibonacci)(遞歸,非遞歸)實現代碼

    c#斐波那契數列(Fibonacci)(遞歸,非遞歸)實現代碼,需要的朋友可以參考一下
    2013-05-05
  • C#制作二維柱狀圖方法

    C#制作二維柱狀圖方法

    在本文里小編為各位分享的是關于C#制作二維柱狀圖方法和步驟,需要的讀者們學習下。
    2018-12-12

最新評論

莱州市| 博湖县| 古浪县| 岳阳县| 江门市| 浪卡子县| 东至县| 同仁县| 张家港市| 开阳县| 苏尼特左旗| 宝兴县| 惠州市| 河源市| 崇州市| 兴宁市| 清流县| 宝坻区| 巩留县| 美姑县| 平度市| 莱州市| 霍城县| 博爱县| 论坛| 温宿县| 富顺县| 咸宁市| 邯郸市| 五寨县| 海原县| 峨眉山市| 福鼎市| 喜德县| 衢州市| 康马县| 鹰潭市| 白朗县| 静海县| 哈尔滨市| 专栏|