RelayCommand는 모든 명령에 대해 생성을 해야되는건가요?

아래처럼 relay패턴 사용시 각 command 마다 RelayCommand를 생성해야 하는지요?

한 페이지에 명령이 20개면 20개의 relaycommand를 생성하는건 너무 비효율적인거 같은데…
제가 잘못알고 있는듯 해서요.

public RelayCommand SearchButtonClickCommand { get; set; }
public RelayCommand DeleteButtonClickCommand { get; set; }

SearchButtonClickCommand = new RelayCommand(SearchButtonClickCommand_Executed);
DeleteButtonClickCommand = new RelayCommand(DeleteButtonClickCommand_Executed);

public void DeleteButtonClickCommand_Executed()
public void SearchButtonClickCommand_Executed()
3개의 좋아요

아닙니다. 명령어는 하나만 쓰고 CommandParameter를 개별로 잘 부여해서 인자로 분기 처리하면 됩니다.

2개의 좋아요

감사합니다.

1개의 좋아요

아래와 같은 식으로 사용하는지요?
param 유형이 한가지이면 문제가 없는데 param 유형이 여러가지 일때는 처리를 어떻게 해야될지 모르겠네요

void RelayCommand_Executed(Object param)
{
    switch(param as string)
    {
        case "search":
            break;
        case "delete":
            break;
    }
}
1개의 좋아요

네. 맞습니다.

param 유형이 다양해도 object 로 받고 is로 분기하시면 됩니다.

1개의 좋아요

예시를 들어봤습니다.

구현을 단순하게 하기 위해 뷰모델을 별도로 두지는 않았고 MainWindow.xaml.cs로 구현했습니다.

다양한 CommandParameter 유형에 대한 예시는 다음과 같습니다.

| MainWindow.xaml

<Window
    x:Class="WpfVariousCommandParameter.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:local="clr-namespace:WpfVariousCommandParameter"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid>
        <StackPanel Orientation="Vertical">
            <Button Command="{Binding ButtonCommand}" CommandParameter="StringParameter">Command1</Button>
            <Button Command="{Binding ButtonCommand}">
                <Button.CommandParameter>
                    <sys:Int32>312</sys:Int32>
                </Button.CommandParameter>
                Command2
            </Button>
            <Button Command="{Binding ButtonCommand}">
                <Button.CommandParameter>
                    <local:ManyParams
                        Boolean="True"
                        Number="312"
                        Text="dimohy" />
                </Button.CommandParameter>
                Command3
            </Button>
            <TextBlock Text="{Binding Message, Mode=OneWay}" />
        </StackPanel>
    </Grid>
</Window>

CommandParameterstring 뿐만 아니라 다양한 타입을 전달할 수 있음을 알 수 있습니다.

| MainWindow.xaml.cs

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

using System.Windows;

namespace WpfVariousCommandParameter;

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>

[INotifyPropertyChanged]
public partial class MainWindow : Window
{
    [ObservableProperty]
    private string _message = default!;

    public MainWindow()
    {
        InitializeComponent();

        DataContext = this;
    }

    [RelayCommand]
    private void OnButton(object args)
    {
        switch (args)
        {
            case string text:
                Message = $"{args.GetType().Name}: {text}";

                break;
            case int num:
                Message = $"{args.GetType().Name}: {num}";

                break;
            case ManyParams manyParams:
                Message = $"{args.GetType().Name}: {manyParams}";

                break;
        }
    }
}

public class ManyParams
{
    public string Text { get; set; } = default!;
    public int Number { get; set; }

    public bool Boolean { get; set; }

    public override string ToString()
    {
        return $"{Text}, {Number}, {Boolean}";
    }
}

CommunityToolkit.Mvvm로 구현해서 형태는 다를 수 있으나 형태만 다를 뿐 명령어 메소드인 OnButton()를 보면, object 타입 인자를 적절한 타입인지를 체크해서 그 타입으로 처리하고 있음을 알 수 있습니다.

만약 .NET이 아닌 .NET Framework를 사용하고 있다면 is 키워드로 if문으로 분기해서 동일한 동작을 할 수 있을꺼에요.

4개의 좋아요

늦은 시간까지 답변 주셔서 감사합니다. 좋은 예제네요… 도움 많이 됐습니다

2개의 좋아요

이런 기능들이 각 화면에 들어가는 공통 기능이라면 BaseViewModel에 구현을 해놓고
실제 ViewModel에서 Execute부분만 구현하는것도 방법일 것 같습니다.

3개의 좋아요