ReactiveProperty의 ReactiveCommand에 sender와 EventArgs를 전달하고 싶습니다.

9265 단어 ReactivePropertyC#WPF
ReactiveCommand에 sender와 EventArgs를 모두 전달하고 싶지만 어떻게해야합니까? ( ´;ω;`)— のかつ(@no_katsu) August 19, 2020


개인적으로는 ViewModel 에 sender 건네주는 것은 어떨까라고 생각합니다만 엄밀하게는 어울리는 기능으로는 할 수 없습니다만, 가까운 것은 할 수 없어도 없습니다. 해보자.



ReactiveProperty.WPF 패키지에 포함된 EventToReactiveCommand 컨버터에는 AssociateObject 속성이 있으며, 여기에 EventTrigger가 할당된 개체의 인스턴스가 들어 있습니다. 이것이 sender 와 일치하는 것이 대부분이라고 생각한다(라고 할까 일치하지 않는 케이스라고 하는 것이겠지) 때문에, 이것과 EventArgs 를 건네주도록(듯이) 컨버터로 처리하면 OK군요.



컨버터는 이런 느낌.




MyConverter.cs

using Reactive.Bindings.Interactivity;
using System;

namespace WpfApp3
{
    public class MyConverter : DelegateConverter<EventArgs, (object sender, EventArgs args)>
    {
        protected override (object sender, EventArgs args) OnConvert(EventArgs source) => (AssociateObject, source);
    }
}



라는 것으로 적당히 ViewModel 을 만들어…




MainWindowViewModel.cs

using Reactive.Bindings;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp3
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public ReactiveCommand<(object sender, EventArgs args)> SomeCommand { get; }
        public ReadOnlyReactivePropertySlim<string> Result { get; }

        public MainWindowViewModel()
        {
            SomeCommand = new ReactiveCommand<(object sender, EventArgs args)>();
            Result = SomeCommand
                .Select(x => $"{DateTime.Now}: {x.sender}, {x.args}")
                .ToReadOnlyReactivePropertySlim();
        }
    }
}



MainWindow.xaml을 다음과 같은 느낌으로 만들어




MainWindow.xaml

<Window
    x:Class="WpfApp3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApp3"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:rp="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <StackPanel>
        <Button Content="Click">
            <behaviors:Interaction.Triggers>
                <behaviors:EventTrigger EventName="Click">
                    <rp:EventToReactiveCommand Command="{Binding SomeCommand}">
                        <local:MyConverter />
                    </rp:EventToReactiveCommand>
                </behaviors:EventTrigger>
            </behaviors:Interaction.Triggers>
        </Button>
        <TextBlock Text="{Binding Result.Value}" />
    </StackPanel>
</Window>



실행하고 버튼을 누르면 Button의 인스턴스와 이벤트 인수가 걸려 있는 것을 확인할 수 있습니다.





요약



그래도 UI 컨트롤을 ViewModel에 직접 전달하고 싶다는 경우는 무엇일까? ?

어쩔 수 없는 상태 이외에서는 하지 않는 것이 좋을까. 확실히 더 좋은 방법이 있기를 바랍니다.


좋은 웹페이지 즐겨찾기