怪奇物语

怪奇物语

首页 新随笔 联系 管理

SetProperty, RelayCommand , AsyncRelayCommand,CommunityToolkit.Mvvm

CommunityToolkit.Mvvm 是一个用于简化创建Model-View-ViewModel (MVVM) 应用程序的库,特别是在使用 .NET 开发时。

它提供了诸如 ObservableObject, RelayCommand, 和 AsyncRelayCommand 等基础组件来帮助开发者快速实现 MVVM 模式。

下面是基于提供的代码示例对 CommunityToolkit.Mvvm 依赖包的用法分析:

SetProperty

在你的项目中,MainViewModel 继承自 ObservableObject,这是 CommunityToolkit.Mvvm 提供的一个基类,用来实现 INotifyPropertyChanged 接口。这使得 ViewModel 中的属性可以在值改变时通知视图(View)进行更新。

public partial class MainViewModel : ObservableObject
{
    private string _name = string.Empty;
    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }
}

这里使用了 SetProperty() 方法来自动处理属性更改的通知逻辑。

RelayCommand 和 AsyncRelayCommand

为了处理用户交互或触发某些操作,你通常需要定义命令。CommunityToolkit.Mvvm 提供了 RelayCommandAsyncRelayCommand 来简化这个过程。

  • RelayCommand: 用于同步命令执行。
public IRelayCommand SayNameCommand { get; }

public MainViewModel()
{
    SayNameCommand = new RelayCommand(OnSayHelloCommand);
}

private void OnSayHelloCommand()
{
    Name = "Hello, World!";
}
  • AsyncRelayCommand: 用于异步命令执行,比如需要等待网络请求或其他耗时操作完成的情况。
public IAsyncRelayCommand ChangeSexCommand { get; }

public MainViewModel()
{
    ChangeSexCommand = new AsyncRelayCommand(OnChangeSexCommand, () => Age >= 18);
}

private async Task OnChangeSexCommand()
{
    await Task.Delay(3000);
    Sex = "F";
}

数据绑定

在 XAML 文件 (MainView.xaml) 中,通过设置控件的 DataContext 属性为 MainViewModel 的实例,实现了数据绑定。这样就可以将 UI 控件与 ViewModel 中的属性和命令连接起来。

<Window.DataContext>
    <local:MainViewModel x:Name="MainViewModel" />
</Window.DataContext>

代码

MainViewModel.cs

using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace DemoMVVM.ViewModels;

public partial class MainViewModel : ObservableObject
{
    /// <summary>
    /// 1. SetProperty()
    /// </summary>
    private string _name = string.Empty;
    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }
    public IRelayCommand SayNameCommand { get; }

    /// <summary>
    /// 2. OnPropertyChanged()
    /// </summary>
    private uint _age;
    public uint Age
    {
        get { return _age; }
        set
        {
            if (SetProperty(ref _age, value))
            {
                ChangeSexCommand.NotifyCanExecuteChanged();
            }
        }
    }
    public IRelayCommand IncreaseAgeCommand { get; }
    public IRelayCommand DecreaseAgeCommand { get; }

    private string _sex = "M";
    public string Sex
    {
        get => _sex;
        set => SetProperty(ref _sex, value);
    }

    /// <summary>
    /// 3.Async Relay Command
    /// </summary>
    public IAsyncRelayCommand ChangeSexCommand { get; }

    public MainViewModel()
    {
        SayNameCommand = new RelayCommand(OnSayHelloCommand);
        IncreaseAgeCommand = new RelayCommand(() => Age++);
        DecreaseAgeCommand = new RelayCommand(() => Age--);
        ChangeSexCommand = new AsyncRelayCommand(OnChangeSexCommand, () => Age >= 18);
    }

    private void OnSayHelloCommand()
    {
        Name = "Hello, World!";
    }

    private async Task OnChangeSexCommand()
    {
        await Task.Delay(3000);
        Sex = "F";
    }
}


MainView.xaml

<Window x:Class="DemoMVVM.Views.MainView"
        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"
        Title="MainView"
        Width="800"
        Height="450"
        WindowStartupLocation="CenterScreen"
        xmlns:local="clr-namespace:DemoMVVM.ViewModels"
        mc:Ignorable="d">

    <Window.DataContext>
        <local:MainViewModel x:Name="MainViewModel" />
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="4*"/>
            <ColumnDefinition Width="6*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="3*"/>
        </Grid.RowDefinitions>

        <Border Background="WhiteSmoke"/>
        <Border Grid.Column ="1" Background="WhiteSmoke"/>
        <Border Grid.Row="1" Grid.ColumnSpan="2" Background="WhiteSmoke"/>

        <StackPanel Grid.Column="0" Margin="20" VerticalAlignment="Center">
            <!-- 新增:用于选择性别的RadioButton组 -->
            <TextBlock Text="请选择炉号:" />
            <RadioButton GroupName="GenderGroup" Content="OVEN-A" IsChecked="{Binding IsMale, Mode=TwoWay}" Width="100" />
            <RadioButton GroupName="GenderGroup" Content="OVEN-B" IsChecked="{Binding IsFemale, Mode=TwoWay}"  Width="100" />
            <Button Content="Set Chamber" Width="100"></Button>
        </StackPanel>

        <StackPanel Grid.Column="1" Margin="40,0,0,0" VerticalAlignment="Center">
            <StackPanel Orientation="Horizontal">
                <Label Content="OpId" Width="50" ></Label>
                <TextBox Foreground="White" FontSize="25" Width="200" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="Lot" Width="50"  ></Label>
                <TextBox Foreground="White" FontSize="25" Width="200" />
            </StackPanel>
        </StackPanel>

        <StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal"
            HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock FontSize="25" Text="High: 66°" Margin="0,0,20,0"/>
            <TextBlock  FontSize="25" Text="Low: 43°" Margin="0,0,20,0"/>
            <TextBlock  FontSize="25" Text="Feels like: 63°"/>
        </StackPanel>

    </Grid>
</Window>
posted on 2025-02-18 08:00  超级无敌美少男战士  阅读(154)  评论(0)    收藏  举报