[WPF] 트리거(Trigger)

728x90

WPF에서 트리거란 이벤트가 발생했을 때 변화를 시키는 것을 의미합니다. 일반적으로 Style의 보조로 많이 사용합니다.

 

 

먼저 트리거 사용법을 알아보겠습니다.

 

1. 일반 트리거

 

style태그 아래에 아래 형식으로 코드를 작성하시면 됩니다.

<Style.Triggers>
    <Trigger Property="Control.이벤트" Value="True">
        <Setter Property="Control.속성" Value="값">      
        </Setter>
    </Trigger>
</Style.Triggers>

 

 

예제로 마우스로 클릭하고 있는 상태일 때 글자색이 빨간색으로 변하는 코드를 만들어보겠습니다.

 

<Window.Resources>
    <Style x:Key="testStyle">
        <Setter Property="Button.Background">
            <Setter.Value>
                
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Black"/>
                        <GradientStop Color="#FF16CEA8" Offset="1"/>
                        <GradientStop Color="#FF0C735E" Offset="0.563"/>
                        <GradientStop Color="#FF0B6C58" Offset="0.533"/>
                    </LinearGradientBrush>
                    
            </Setter.Value>
            
        </Setter>
        <Style.Triggers>
            <!--컨트롤의 IsMouseCaptured 속성이 true일때 트리거 동작-->
            <Trigger Property="Control.IsMouseCaptured" Value="True">
                <Setter Property="Control.Foreground" Value="Red">      
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

 

실행결과

 

글자색이 변하는 것을 확인할 수 있습니다.

 

 

2. 데이터트리거

데이터 트리거의 사용법은 아래와 같습니다.

 

 <Style.Triggers>
     <DataTrigger Binding="{Binding ElementName=컨트롤의 x:name,Path=이벤트}" Value="값">
         <Setter Property="Control.속성" Value="값"></Setter>
	<Setter Property="Control.속성" Value="값"></Setter>
         
     </DataTrigger>
 </Style.Triggers>

 

 

<setter>는 여러개를 걸 수도 있습니다.

 

예제를 보겠습니다.

 

체크박스 클릭시 style이 있는 컨트롤이 보이지 않도록 하겠습니다.

<Window.Resources>
    <Style x:Key="testStyle">
        <Setter Property="Button.Background">
            <Setter.Value>
                
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Black"/>
                        <GradientStop Color="#FF16CEA8" Offset="1"/>
                        <GradientStop Color="#FF0C735E" Offset="0.563"/>
                        <GradientStop Color="#FF0B6C58" Offset="0.533"/>
                    </LinearGradientBrush>
                    
            </Setter.Value>
            
        </Setter>
        <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=check1,Path=IsChecked}" Value="True">
                <Setter Property="Control.Foreground" Value="Purple"></Setter>
                
                <Setter Property="Control.Visibility" Value="Hidden"></Setter>
                
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

 

실행결과

 

체크되지 않았을 때

 

체크되었을 때

 

 

예제2)

클래스를 생성하고 객체를 생성하여 객체의 속성이 변겨오디면 해당 속성값대로 프로그래스바가 움직이도록 만들어보겠습니다.

 

먼저 프로젝트를 우클릭하여 새항목을 클릭한 후 ViewModels라는 폴더를 만듭니다.

 

그리고 ViewModels 폴더안에 MainViewModel이라는 클래스를 만듭니다.

 

그리고 아래와 같은 코드를 추가합니다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp2.ViewModels
{
    //INotifyPropertyChanged는 바인딩이 업데이트되도록 뷰(화면)에게 알려줍니다.
    internal class MainViewModel : INotifyPropertyChanged
    {

        private int progressValue;

        public int ProgressValue
        {
            get { return progressValue; }
            set { progressValue = value; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

       
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

 

 

그리고 MainWindow.xaml에서 프로그래스바 컨트롤을 추가합니다.

value에는 바인딩 설정을 합니다.

 

Binding값으로는 public 인 ProgressValue를 넣어야 인식합니다.

<ProgressBar x:Name="progressBar1"  Width="200" Height="20" Value="{Binding ProgressValue}"></ProgressBar>

 

기본값으로 30퍼센트가 채워져있도록 해보겠습니다.

 

using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WpfApp2.ViewModels;

namespace WpfApp2
{
    
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        MainViewModel viewModel;

        public MainWindow()
        {
            InitializeComponent();

            viewModel = new MainViewModel();

            //MainWindow의 바인딩 경로의 시작점이 됨
            viewModel.ProgressValue = 30;
            DataContext = viewModel;

        }
    }
}

 

실행결과

 

 

버튼 클릭시 100%로 채워지도록 해보겠습니다.

 

MainWindow.cs

using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WpfApp2.ViewModels;

namespace WpfApp2
{
    
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        MainViewModel viewModel;

        public MainWindow()
        {
            InitializeComponent();

            viewModel = new MainViewModel();

            //MainWindow의 바인딩 경로의 시작점이 됨
            viewModel.ProgressValue = 30;
            DataContext = viewModel;

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //버튼 클릭시 프로그레스바 100으로 변환
            viewModel.ProgressValue = 100;
                        
            
        }
    }
}

 

 

이렇게 코드를 작성하고 실행하면 100으로 변하지 않을 것입니다. 여기서 추가해야될 코드가 있습니다.

 

MainViewModel.cs에서 set부분을 수정해야 합니다.

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp2.ViewModels
{
    //INotifyPropertyChanged는 바인딩이 업데이트되도록 뷰(화면)에게 알려줍니다.
    internal class MainViewModel : INotifyPropertyChanged
    {

        private int progressValue;

        public int ProgressValue
        {
            get { return progressValue; }

            //수정할 부분
            set 
            { 
                progressValue = value;

                //값이 변경되면 화면도 변경되게 하는 기능
                //NotifyPropertyChanged(nameof(변수 또는 객체))
                NotifyPropertyChanged(nameof(ProgressValue));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

       
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

 

 

이렇게 코드를 입력하고 실행하면 버튼 클릭 시 프로그레스바가 100으로 변경됩니다.

 

이제는 프로그레스바가 100으로 변경될 때 라벨과 버튼이 보이지 않도록 해보겠습니다.

 

MainWindow.xaml에 아래코드를 추가하겠습니다.

<Style.Triggers>
    <!--progressBar1의 value가 100이면 동작-->
    <DataTrigger Binding="{Binding ElementName=progressBar1,Path=Value}" Value="100">

        <Setter Property="Control.Visibility" Value="Hidden"></Setter>

    </DataTrigger>
</Style.Triggers>

 

실행결과

 

3. 애니메이션

<Window x:Class="WpfAnimation.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:WpfAnimation"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
            <Grid.Triggers>
                <!--그리드 패널이 로드가 되면 애니메이션이 작동-->
                <EventTrigger RoutedEvent="Loaded">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Opacity"
                                             From="0" To="1"
                                             Duration="0:0:5"
                                             />
                            <!--듀레이션은 시간단위 시간:분:초-->

                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Width"
                             From="0" To="350"
                             Duration="0:0:5"
                             />


                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Grid.Triggers>
            <Label FontSize="30">안녕하세요</Label>
            <Button Grid.Column="1">버튼</Button>
        
    </Grid>
        <Label FontSize="30">안녕하세요2
            <Label.Triggers>
                <EventTrigger RoutedEvent="MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Width"
             From="0" To="350"
             Duration="0:0:5"
             />


                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Label.Triggers>
        </Label>
    </StackPanel>
</Window>

 

코드를 작성하고 실행해보면 애니메이션이 작동하는 것을 확인할 수 있습니다.

 

trigger는 모든 컨트롤에 있기 때문에 필요한 컨트롤에 이벤트 트리거를 만들어 사용하면 됩니다.

'C# Programming > WPF' 카테고리의 다른 글

[WPF] Settings.settings 만들기  (0) 2024.05.16
[WPF] 동기, 비동기 RelayCommand  (0) 2024.05.16
[WPF] 스타일(Xaml 리소스)  (0) 2024.05.16
[WPF] 모델 생성과 바인딩  (0) 2024.05.16
[WPF] 컨트롤 사용방법  (2) 2024.05.13