프로그래밍/WPF

[WPF] DataGrid에서 SelectedItems를 ViewModel과 바인딩하는 방법

흔한티벳여우 2023. 3. 27. 15:15
반응형

오늘은 WPF DataGrid에서 선택된 항목들(SelectedItems)을 ViewModel과 바인딩하는 방법에 대해 알아보겠습니다. WPF의 DataGrid는 강력한 기능을 제공하지만, 선택된 항목들을 ViewModel에 직접 바인딩하는 기능은 제공하지 않습니다. 그러나 Blend SDK의 Behavior<T> 클래스를 활용하여 이 문제를 해결할 수 있습니다.

먼저, DataGridSelectedItemsBehavior라는 이름의 새 클래스를 생성하고, 이 클래스를 Behavior<DataGrid>로 상속합니다.

public class DataGridSelectedItemsBehavior : Behavior<DataGrid>
{
    // ...
}

 

다음으로, SelectedItems라는 DependencyProperty를 정의합니다. 이 프로퍼티는 DataGrid의 선택된 항목들을 저장하며, Two-Way 바인딩을 지원합니다.

public static readonly DependencyProperty SelectedItemsProperty =
    DependencyProperty.Register("SelectedItems", typeof(IList), typeof(DataGridSelectedItemsBehavior), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedItemsChanged));

public IList SelectedItems
{
    get { return (IList)GetValue(SelectedItemsProperty); }
    set { SetValue(SelectedItemsProperty, value); }
}

그 후, OnAttached()OnDetaching() 메서드를 오버라이드하여 DataGrid의 SelectionChanged 이벤트에 대한 처리를 추가합니다.

protected override void OnAttached()
{
    base.OnAttached();
    AssociatedObject.SelectionChanged += OnSelectionChanged;
}

protected override void OnDetaching()
{
    base.OnDetaching();
    AssociatedObject.SelectionChanged -= OnSelectionChanged;
}

OnSelectedItemsChanged() 메서드를 정의하여 SelectedItems 프로퍼티가 변경될 때 적절한 처리를 수행합니다.

private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var behavior = d as DataGridSelectedItemsBehavior;
    if (behavior != null)
    {
        behavior.SelectedItems = e.NewValue as IList;
    }
}

마지막으로, OnSelectionChanged() 메서드를 구현하여 DataGrid의 선택된 항목들을 SelectedItems 프로퍼티에 동기화합니다.

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // Check if the original source of the event is the DataGrid itself.
    if (e.OriginalSource != sender) return;

    if (SelectedItems != null)
    {
        foreach (var item in e.AddedItems)
        {
            if (!SelectedItems.Contains(item))
            {
                SelectedItems.Add(item);
            }
        }

        foreach (var item in e.RemovedItems)
        {
            if (SelectedItems.Contains(item))
            {
                SelectedItems.Remove(item);
            }
        }
    }
}

 

이제 XAML 코드에서 DataGridSelectedItemsBehavior를 사용하여 DataGrid의 SelectedItems를 ViewModel과 바인딩할 수 있습니다.

<Window ...
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:local="clr-namespace:YourNamespace">
    <!-- ... -->
    <DataGrid ItemsSource="{Binding YourItemsSource}" AutoGenerateColumns="False">
        <i:Interaction.Behaviors>
            <local:DataGridSelectedItemsBehavior SelectedItems="{Binding SelectedItemsInViewModel}" />
        </i:Interaction.Behaviors>
        <!-- ... -->
    </DataGrid>
    <!-- ... -->
</Window>

위의 코드에서는 DataGridSelectedItems를 ViewModel의 SelectedItemsInViewModel 프로퍼티와 바인딩하고 있습니다. 이렇게하면 ViewModel에서 선택된 항목들을 직접 조작할 수 있게 됩니다.

 

이상으로 WPF DataGrid에서 SelectedItems를 ViewModel과 바인딩하는 방법에 대해 설명했습니다. 이 방법을 사용하면 ViewModel에서 선택된 항목들을 쉽게 관리할 수 있으며, MVVM 패턴에 더 잘 어울리게 됩니다.

 

반응형