본문 바로가기
프로그래밍&IT/C# (Winfrom, WPF)

[WPF] Styles and Behaviors

by 성장의 용 2025. 8. 9.
728x90
반응형

1. Styles

여러 속성 설정(예: 글꼴, 색상 등)을 재사용 가능한 형식으로 묶어, 다양한 컨트롤에 적용할 수 있는 기능.

→ GreenItalicButtonStyle 같은 스타일을 만들어 버튼에 통일 적용

일반적인 예시

<Style x:Key="BigFontButtonStyle">
  <Setter Property="Control.FontFamily" Value="Times New Roman"/>
  <Setter Property="Control.FontSize" Value="17"/>
  <Setter Property="Control.FontWeight" Value="Bold"/>
</Style>

스타일 기반 확장

ex) 마우스 오버 시 배경을 빨간색으로, 마우스 진입 시 2초 동안 폰트 크기를 22로 애니메이션을 보여주는 스타일
 → 이 스타일을 재사용하면서 트리거와 애니메이션 기능을 추가

<Style x:Key="EmphasizedBigFontButtonStyle" BasedOn="{StaticResource BigFontButtonStyle}">
  <Setter Property="Control.Foreground" Value="White"/>
  <Setter Property="Control.Background" Value="Green"/>
  <Style.Triggers>
    <Trigger Property="Control.IsMouseOver" Value="True">
      <Setter Property="Control.Background" Value="Red"/>
    </Trigger>
    <EventTrigger RoutedEvent="Mouse.MouseEnter">
      <EventTrigger.Actions>
        <BeginStoryboard>
          <Storyboard>
            <DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="FontSize" To="22" />
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger.Actions>
    </EventTrigger>
  </Style.Triggers>
</Style>

Trigger에 대해서

XAML에서 조건에 따라 속성 값을 변경하거나 동작을 실행하게 만드는 핵심 기능이며 크게 속성 기반이벤트 기반으로 나뉜다.

1) Property Trigger

 

  • 특정 속성(Property) 값이 조건과 일치할 때 동작.
  • 가장 기본적인 트리거.
  • 스타일, 컨트롤 템플릿, 데이터 템플릿에서 사용 가능.

- 마우스 오버 시 버튼 배경을 노란색으로 변경.

<Style TargetType="Button">
    <Setter Property="Background" Value="LightGray"/>
    <Trigger Property="IsMouseOver" Value="True">
        <Setter Property="Background" Value="Yellow"/>
    </Trigger>
</Style>

 

2) MultiTrigger

 

  • 여러 속성 조건이 동시에 만족될 때만 동작.
  • 조건이 많을수록 UI 상태를 더 정밀하게 제어 가능.

- 마우스를 올리고 버튼을 누른 상태일 때 배경을 주황색으로 변경.

 

<Style TargetType="Button">
    <Setter Property="Background" Value="LightGray"/>
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="IsMouseOver" Value="True"/>
            <Condition Property="IsPressed" Value="True"/>
        </MultiTrigger.Conditions>
        <Setter Property="Background" Value="Orange"/>
    </MultiTrigger>
</Style>

3) DataTrigger

 

  • 데이터 바인딩된 값에 따라 동작.
  • ViewModel, 바인딩 값에 따라 UI 변경할 때 주로 사용.

 

<Style TargetType="TextBlock">
    <Setter Property="Foreground" Value="Black"/>
    <DataTrigger Binding="{Binding Status}" Value="Error">
        <Setter Property="Foreground" Value="Red"/>
    </DataTrigger>
</Style>

4) MultiDataTrigger

 

  • 여러 데이터 바인딩 조건이 동시에 참일 때만 동작.
  • DataTrigger의 다중 조건 버전.

Status가 "Error"이고 IsCritical이 True일 때 글자색을 진한 빨간색으로 변경

 

<Style TargetType="TextBlock">
    <Setter Property="Foreground" Value="Black"/>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding Status}" Value="Error"/>
            <Condition Binding="{Binding IsCritical}" Value="True"/>
        </MultiDataTrigger.Conditions>
        <Setter Property="Foreground" Value="DarkRed"/>
    </MultiDataTrigger>
</Style>

5) EventTrigger

 

  • 이벤트 발생 시 동작.
  • 주로 애니메이션 시작/정지에 사용.
  • RoutedEvent를 지정해야 함
<Button Content="Hover Me">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Mouse.MouseEnter">
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation 
                        Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" 
                        To="LightGreen" Duration="0:0:1"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

 

조건 유형별 : 속성값 / 바인딩값 / 이벤트 발생

 

2. behaviors (행동)

컨트롤의 동작을 XAML 수준에서 재사용 가능한 방식으로 확장하는 메커니즘

 

  • 버튼 클릭 시 연동된 커맨드 자동 실행
  • 드래그 앤 드롭 동작 또는 복잡한 사용자 인터랙션을 XAML에서 재사용 가능하게 캡슐화

2010 시절에는 Blend SDK(현재는 Microsoft.Xaml.Behaviors.Wpf NuGet 패키지로 제공됨) 를 사용해

Behavior<T> 클래스를 상속받아 컨트롤의 동작을 XAML에서 쉽게 붙였다 뗄 수 있도록 만드는 방식을 많이 사용했었음.

1) Nuget패키지 설치

Microsoft.Xaml.Behaviors.Wpf

 

2) Behavior 예제 : 버튼 클릭 시 메시지 출력 ( ClickMessageBehavior.cs)

using System.Windows;
using System.Windows.Controls;
using Microsoft.Xaml.Behaviors; // NuGet 패키지 필요

public class ClickMessageBehavior : Behavior<Button>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Click += OnButtonClick;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.Click -= OnButtonClick;
        base.OnDetaching();
    }

    private void OnButtonClick(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Behavior: 버튼이 클릭되었습니다!");
    }
}

3) xaml에서 behavior 사용 (MainWindow.xaml)

<Window x:Class="BehaviorSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:local="clr-namespace:BehaviorSample"
        Title="Behavior Demo" Height="200" Width="300">

    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
        <Button Content="Click Me" Width="100" Height="40">
            <i:Interaction.Behaviors>
                <local:ClickMessageBehavior/>
            </i:Interaction.Behaviors>
        </Button>
    </StackPanel>
</Window>

동작설명

 

  • ClickMessageBehavior는 Button을 대상으로 함 (Behavior<Button>).
  • XAML에서 <i:Interaction.Behaviors> 태그로 Button에 Behavior를 붙임.
  • 버튼 클릭 시 Behavior에서 메시지 박스를 띄움.
  • 동일 Behavior를 다른 버튼에도 붙일 수 있어 재사용성이 매우 높음.

최신 버전과의 차이?

기본 개념은 동일하지만 구현. 배포 방식이 달라졌다고 함.

1) Blend SDK > Nuget 패키지로

 

  • 예전: System.Windows.Interactivity 네임스페이스가 Expression Blend SDK에 포함되어 있었음.
  • 지금: Blend SDK는 더 이상 기본 제공되지 않고, Microsoft.Xaml.Behaviors.Wpf 패키지를 NuGet으로 직접 설치해야 함.
  • 네임스페이스도 변경됨:
    • 예전: System.Windows.Interactivity
    • 현재: Microsoft.Xaml.Behaviors

 

2) 클래스 구조는 거의 동일

  • 여전히 Behavior<T>와 TriggerAction<T>를 사용.
  • 동작 방식(Attached/Detached, AssociatedObject)은 그대로.
  • 구버전 Behavior 코드도 네임스페이스만 바꾸면 대부분 그대로 동작

 

3) Visual Studio Designer 지원 변화

  • 예전: Blend 통합 → Visual Studio에서 Blend 디자인 기능을 그대로 사용 가능.
  • 현재: Blend 기능은 여전히 제공되지만, 별도의 Blend 프로그램 없이 VS의 XAML Designer에서 Behavior를 붙일 수 있음
  • 단, VS Designer에서는 Behavior 미리보기 동작은 제한적.

4) EventTrigger 사용 변화

  • 예전에는 EventTrigger와 InvokeCommandAction을 Behavior 패키지에서 함께 썼음.
  • 현재도 동일하지만, MVVM 패턴에서는 Prism, CommunityToolkit.Mvvm 등의 프레임워크가 자체적으로 Command Behavior를 제공하는 경우가 많아, NuGet Behavior를 꼭 쓰지 않아도 됨.

예) 최신 MVVM에서 버튼의 마우스 오버 동작을 Behavior 없이도 Command 바인딩으로 처리 가능.

5) 추가된 & 변화된 점

  • UWP/WinUI XAML Behaviors와 네임스페이스/구현이 호환되도록 통합 관리.
  • Behavior를 WPF → WinUI로 이식할 때 코드 변경량이 줄어듦.
  • 일부 예전 Blend SDK 전용 타입은 deprecated

'프로그래밍&IT > C# (Winfrom, WPF)' 카테고리의 다른 글

[WPF] Geometries and Drawings  (2) 2025.08.09
[WPF] Shapes, Brushes and Transforms  (1) 2025.08.09
[WPF] Resources  (3) 2025.08.07
[WPF] Commands  (0) 2025.08.06
[WPF] Element Binding  (4) 2025.08.04