wpf에서 Mvvm패턴을 지키면서 Grid에 클릭하는 방법입니다.
기존의 Grid는 Click 이벤트를 실행 할 수 없으나 Behavior를 사용하면 Grid에서도 클릭이벤트 사용이 가능합니다.
1.NuGet에서 Behaviors를 다운 받습니다.
2.xaml파일에 해당 문구를 넣어줍니다.
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
3.ViewModel 클래스에 Behavior 클래스를 상속합니다.
Behavior<지정할 컴포넌트 클래스> 이처럼 지정할 컨트롤 클래스를 명시해줍니다.
internal class GridBehavior : Behavior<Grid>
4. OnAttached(),OnDetaching()를 구현합니다.
OnAttached를 통해 연결된 컨트롤 객체와 이벤트를 연결하고
OnDetaching을 통해 이벤트를 해제 합니다.
protected override void OnAttached()
{
//AssoicatedObject의 이벤트 핸들러 추가
AssociatedObject.MouseDown += AssociatedObject_MouseDown;
}
protected override void OnDetaching()
{
//이벤트 핸들러 삭제
AssociatedObject.MouseDown -= AssociatedObject_MouseDown;
}
5. 연결한 이벤트를 구현하여 실제로 실행될 로직을 입력합니다. 이때 Dispatcher를 사용해야 해당 스레드에 접근 가능합니다.
private void AssociatedObject_MouseDown(object sender, System.Windows.Input.MouseEventArgs e)
{
//Dispatcher를 사용해야 해당 스레드에 접근할 수 있다.
Dispatcher.BeginInvoke(DispatcherPriority.Background,(new Action(() =>
{
System.Windows.Forms.MessageBox.Show("그리드 클릭");
})));
}
6.바인딩 시킬 객체를 생성합니다.
public ICommand ClickCommand
{
get { return (ICommand)GetValue(ClickCommandProperty); }
set { SetValue(ClickCommandProperty, value); }
}
7. DependencyProperty를 사용하여 바인딩 해줍니다.
DependencyProperty는 Register를 통해 인스턴스와 클래스를 매핑하여 등록합니다.
public static readonly DependencyProperty ClickCommandProperty =
DependencyProperty.Register(nameof(ClickCommand), typeof(ICommand), typeof(GridBehavior), new PropertyMetadata(null));
8.xaml에 Interaction.Behaviors를 통해 xaml과 객체를 바인딩 시켜줍니다.
- 색상을 지정해야 클릭하는 이벤트가 제대로 실행되며 색상이 없으면 실행이 안됩니다.
<Grid Background="White">
<i:Interaction.Behaviors>
<local:GridBehavior ClickCommand="{Binding ClickCommand}" />
</i:Interaction.Behaviors>
</Grid>
예제) 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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp3"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Background="White">
<i:Interaction.Behaviors>
<local:GridBehavior ClickCommand="{Binding ClickCommand}" />
</i:Interaction.Behaviors>
</Grid>
</Window>
예제) Behavior클래스
using Microsoft.Xaml.Behaviors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Threading;
namespace WpfApp3
{
internal class GridBehavior : Behavior<Grid>
{
protected override void OnAttached()
{
//AssoicatedObject의 이벤트 핸들러 추가 - 삭제는 반드시 쌍으로 처리합니다.
AssociatedObject.MouseDown += AssociatedObject_MouseDown;
}
private void AssociatedObject_MouseDown(object sender, System.Windows.Input.MouseEventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.Background,(new Action(() =>
{
System.Windows.Forms.MessageBox.Show("그리드 클릭");
})));
}
protected override void OnDetaching()
{
AssociatedObject.MouseDown -= AssociatedObject_MouseDown;
}
public ICommand ClickCommand
{
get { return (ICommand)GetValue(ClickCommandProperty); }
set { SetValue(ClickCommandProperty, value); }
}
public static readonly DependencyProperty ClickCommandProperty =
DependencyProperty.Register(nameof(ClickCommand), typeof(ICommand), typeof(GridBehavior), new PropertyMetadata(null));
}
}
'c#' 카테고리의 다른 글
WPF DataTemplate과 ControlTemplate ItemsPanelTemplate (0) | 2023.03.21 |
---|---|
WPF static Resource 와 dynamic Resource의 차이점 (0) | 2023.03.12 |
C# wpf Dispatcher DispatcherObjcet사용법 및 정의 (0) | 2023.03.08 |
c# image to byte 이미지 바이트로 전환, 이미지 압축 하는 법 (0) | 2023.02.27 |
c# 보조 키 이벤트 , 컨트롤 키 추가 이벤트 넣는 법 (0) | 2023.02.20 |