티스토리 뷰

반응형

 

다음 카페에 질문 올려주신 내용에 대해서 간단한 소스를 만들었습니다.

닷넷 (.NET) 프로그래머 모임 | MVVM과 combobox에 대한 질문드립니다. - Daum 카페

 

1. NuGet Packages

Microsoft.Toolkit.Mvvm

Microsoft.Xaml.Behaviors.Wpf

2. View (XAML)

<Window
    x:Class="WpfCombo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfCombo"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock FontSize="30" Text="ComboBox Sample" />
            <ComboBox ItemsSource="{Binding EnumStrings}">
                <b:Interaction.Triggers>
                    <b:EventTrigger EventName="SelectionChanged">
                        <b:InvokeCommandAction Command="{Binding SelectionChangedCommand}" PassEventArgsToCommand="True" />
                    </b:EventTrigger>
                </b:Interaction.Triggers>
            </ComboBox>
        </StackPanel>
    </Grid>
</Window>

- Window.DataContext : 뷰모델을 뷰와 연결 시키고 있습니다.

- xmlns:b="http://schemas.microsoft.com/xaml/behaviors" : Behavior를 사용하기 위한 네임 스페이스 입니다.

- ComboBox는 Command 프로퍼티를 가지고 있지 않습니다. 그래서 ComboBox에서 발생하는 이벤트와 Command를 연결하기 위해서는 EventTrigger를 사용하고 InvokeCommandAction을 이용해 주어야합니다. 이러한 이련의 과정에는 꼭 Behavior nuget package가 필요 합니다.

- 위의 예제에서 SelectionChanged 이벤트를 SelectionChangedCommand와 연결을 했습니다.

- PassEventArgsToCommand="True" 이 코드는 이벤트가 발생할때 함께 전달되는 이벤트 Args를 CommandParameter에 넣어서 뷰모델에 전달할지 여부를 지정하게 됩니다.

3. ViewModel (c#)

using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfCombo
{
    public class MainWindowViewModel : ObservableObject
    {
        private IList<string> _enumStrings = new List<string>();

        public IList<string> EnumStrings
        {
            get => _enumStrings;
            set => SetProperty(ref _enumStrings, value);
        }

        public ICommand SelectionChangedCommand { get; set; }

        public MainWindowViewModel()
        {
            foreach (object item in Enum.GetValues(typeof(TestEnum)))
            {
                EnumStrings.Add(item.ToString());
            }

            SelectionChangedCommand = new RelayCommand<object>(OnSelectionChanged);
        }

        private void OnSelectionChanged(object obj)
        {
            SelectionChangedEventArgs args = obj as SelectionChangedEventArgs;
            if (args == null)
            {
                return;
            }

            object selectedItem = args.AddedItems[0];
            MessageBox.Show($"You selected is {selectedItem}");
        }
    }
}

- Microsoft mvvm nuget pacakge는 ObservableObject를 상속받아야 프로퍼티 체인지 이벤트를 발생시킬 수 있습니다.

- Microsoft mvvm nuget pacakge에서는 RelayCommand를 이용합니다. 

- SelectionChangedCommand를 RelayCommand로 초기화 합니다. 그런데, 뷰에서 CommandParameter를 이용하는 경우에는 입력되는 값의 type을 지정해서 생성합니다. 여기서는 object type이 입력된다고 설정했습니다.

- OnSelectionChanged는 실제 커맨드가 실행하는 메소드 입니다.

- 전달받은 obj의 형변환을 하고 args.AddedItems[0]을 이용해서 선택된 아이템을 반환합니다.

- MessageBox.Show를 호출해서 출력합니다.

4. 소스

WpfTest/WpfCombo at master · kaki104/WpfTest · GitHub

반응형
댓글