실버라이트 이벤트
이벤트: 특정 동작의 발생을 알리기 위해 객체에서 보내는 메시지
01 이벤트 종류
입력 이벤트: 사용자의 입력이 있는 경우 호출되는 이벤트
비 입력 이벤트: 객체의 상태가 변경된 경우 호출되는 이벤트
02 이벤트 핸들러 생성 방법
이벤트 핸들러: 이벤트가 발생했을 때 이를 처리하는 코드를ㄹ 의미
XAML을 이용해 이벤트 핸들러 연결하기
<UserControl x:Class="EventHandlerXAML.MainPage" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" > <Button Width="100" Height="100" Content="이벤트 버튼" Click="Button_Click" /> </Grid> </UserControl> |
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes;
namespace EventHandlerXAML { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { MessageBox.Show("버öo튼¡¡Æ이I 클¡þ릭¬?되ìC었úu습öA니¥I다¥U"); } } } |
C# 코드를 이용해 동적으로 이벤트 핸들러 연결하기
<Grid x:Name="LayoutRoot" > <Button x:Name="MyButton" Width="100" Height="100" Content="이벤트 버튼" /> </Grid> |
public partial class MainPage : UserControl { public MainPage() { InitializeComponent();
MyButton.Click += new RoutedEventHandler(Button_Click); }
void Button_Click(object sender, RoutedEventArgs e) { MessageBox.Show("버튼이 클릭 되었습니다"); }
} |
03 이벤트 라우팅
실버라이트의 모든 객체들은 서로의 포함 관계에 따라 위, 아래 개념을 가집니다
트리 구조: 최상위에 객체가 하나 존재하고 그 아래로 다수의 객체가 존재하는 구조를 말합니다
<Grid> <Canvas> <Rectangle Fill="Red"></Rectangle> <Button Content="button"/> </Canvas>
<StackPanel> <TextBlock Text="Text 1"/> <TextBlock Text="Text 2"/>
<Canvas> <Button></Button> </Canvas> </StackPanel> </Grid> |
실버라이트의 객체들은 앞에서 본 것과 같이 상, 하위 개념을 가지며 만약 가장 하위에 있는 객체에서 이벤트가 발생하면 이벤트는 하위에서 상위로 한 단계씩 올라가면서 발생
트리 구조를 따라 이벤트가 발생하는 방식을 이벤트 라우팅이라고 함
아래서 위로 올라가는 이벤트 라우팅 방식(버블링)
위에서 아래로 내려오는 이벤트 라우팅(터널링)
<Grid x:Name="LayoutRoot" Background="Beige" Width="400" Height="300"> <Rectangle x:Name="MyRectangle" Width="100" Height="100" Fill="Khaki"></Rectangle> </Grid> |
public MainPage() { InitializeComponent();
//Grid에¯이벤트 핸들러 연결 LayoutRoot.MouseLeftButtonDown += new MouseButtonEventHandler(Grid_Handler);
//Rectangle에 이벤트 핸들러 연결 MyRectangle.MouseLeftButtonDown +=new MouseButtonEventHandler(Rectangle_Handler); } //Grid 이벤트 핸들러 void Grid_Handler(object sender, MouseButtonEventArgs e) { MessageBox.Show("Grid의 이벤트 핸들러"); } //Rectangle 이벤트 핸들러 void Rectangle_Handler(object sender, MouseButtonEventArgs e) { MessageBox.Show("Rectangle 이벤트 핸들러"); } |
이벤트 라우팅 중지하기
public MainPage() { InitializeComponent();
//Grid에¯이벤트 핸들러 연결 LayoutRoot.MouseLeftButtonDown += new MouseButtonEventHandler(Grid_Handler);
//Rectangle에 이벤트 핸들러 연결 MyRectangle.MouseLeftButtonDown +=new MouseButtonEventHandler(Rectangle_Handler); } //Grid 이벤트 핸들러 void Grid_Handler(object sender, MouseButtonEventArgs e) { MessageBox.Show("Grid의 이벤트 핸들러"); } //Rectangle 이벤트 핸들러 void Rectangle_Handler(object sender, MouseButtonEventArgs e) { MessageBox.Show("Rectangle 이벤트 핸들러");
//이벤트가 더 이상 상단으로 전달되지 않도록 한다 e.Handled = true; } |
이벤트를 발생시킨 원본 객체 접근하기
<Grid x:Name="LayoutRoot"> <Rectangle x:Name="RedRectangle" Fill="Red" Width="100" Height="100" Margin="148,83,152,117"></Rectangle> <Rectangle x:Name="BlueRectangle" Fill="Blue" Width="100" Height="100" Canvas.Left="120" Margin="26,12,274,188" /> <Rectangle x:Name="YellowRectangle" Fill="Yellow" Width="100" Height="100" Canvas.Left="240" Margin="254,142,46,58" /> </Grid> |
public MainPage() { InitializeComponent();
LayoutRoot.MouseLeftButtonDown += new MouseButtonEventHandler(Canvas_Handler); }
void Canvas_Handler(object sender, MouseButtonEventArgs e) { //originalSource를¬rectangle로 캐스팅 Rectangle rect = (Rectangle)e.OriginalSource;
//선택된 rectangle의 이름을 메시지 박스로 출력 MessageBox.Show("originalsource:" + rect.Name); } |
04 트리거와 액션
트리거와 액션은 완벽히 XAML만을 이용해 사용할 수 있으며, 코드 비하인드 없이도 미리 정의되어있는 액션을 이용해 이벤트를 처리를 수행할 수 있음
트리거(방아쇠): 이벤트를 설정할 수 있음
액션: 트리거의 하위에 포함되는 자식 요소. 트리거가 실행되면 실제로 수행되어야 할 작업을 정의할 수 있음
Triggers와 EventTrigger
Triggers 엘리먼트는 컨트롤의 하위에 선언하며, 다수의 EventTrigger를 하위에 선언가능
EventTrigger는 Triggers 엘리먼트 하위에 선언하며, 트리거를 발생시키기 위한 이벤트 이름 설정 가능
*EventTrigger 의 2가지 프로퍼티 속성
EventName – 트리거를 발생시키기 위한 이벤트의 이름을 의미
SourceName – 이벤트를 처리할 컨트롤의 이름을 의미, Default는 Triggers 엘리먼트가 선언된 컨트롤의 이벤트
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" // 트리거를 사용하기 위해 네임스페이스를 추가 xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions" // 액션을 사용하기 위해 네임스페이스를 추가 mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White"> <Button Content="Click Me" x:Name="button" Width="100" Height="100"> <i:Interaction.Triggers> //태그를 설정해 트리거를 정의할 준비 <i:EventTrigger EventName="Click"> //트리거 선언, eventname 은 트리거를 발생시킬 이벤트 이름을 의미 <ic:ChangePropertyAction PropertyName="Width" TargetName="button" Value="200"></ic:ChangePropertyAction> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> |
Action
EventTrigger 하위에 포함되어 트리거에 의해 수행
Blend툴을 설치하면 기본적으로 사용할 수 있는 액션은 총 6가지 이며 크게 2가지 그룹으로 나뉨
05 TargetedTriggerAction 그룹
액션을 적용할 대상을 설정할 수 있는 기능을 제공
액션을 적용할 대상을 가리키기 위해 TargetName 프로퍼티를 가지며 이 프로퍼티에 컨트롤의 이름을 명시
ChangePropertyAction
Target 컨트롤의 프로퍼티 값을 변경하기 위해 사용
TargetName: ChangePropertyAction으로 변경시키고자 하는 컨트롤의 이름
PropertyName: 변경시킬 컨트롤의 프로퍼티 이름
Value: 변경될 값
Ease: 컨트롤의 값이 변경될 때 사용할 애니메이션을 지정 가능
Duration: Duration은 Ease 프로퍼티가 설정된 경우에만 의미가 있는 프로퍼티로, 애니메이션의 재생 시간을 의미
<Grid x:Name="LayoutRoot" Width="400"> <Button Content="ChangedPropertyAction" Width="100" Height="100" HorizontalAlignment="Left"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> //버튼에 트리거를 선언 <ic:ChangePropertyAction TargetName="rect1" PropertyName="Width" Value="120" /> <ic:ChangePropertyAction TargetName="rect2" PropertyName="Height" Value="120"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Rectangle x:Name="rect1" Fill="Red" Width="100" Height="100" HorizontalAlignment="Right"/> </Grid> |
GoToStateAction
컨트롤의 VisualState를 변경시키기 위해 사용
VisualState는 현재 컨트롤의 상태를 의미
TargetName: GoToStateAction으로 변경시키고자 하는 컨트롤의 이름
StateName: 변경될 State의 이름
<Grid x:Name="LayoutRoot" Width="400"> <Button Content="GoToStateAction" Width="100" Height="100" HorizontalAlignment="Left"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ic:GoToStateAction TargetName="button1" StateName="MouseOver"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button x:Name="button1" Width="100" Height="100" Content="StateTest" HorizontalAlignment="Right"/> </Grid> |
RemoveElementAction
컨트롤을 삭제하기 위해 사용
TargetName: RemoveElementAction으로 삭제하고자 하는 컨트롤의 이름
<Grid x:Name="LayoutRoot" Width="400"> <Button Content="RemoveElementAction" Width="140" Height="100" HorizontalAlignment="Left"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ic:RemoveElementAction TargetName="rect1"></ic:RemoveElementAction> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Rectangle x:Name="rect1" Fill="Red" Width="100" Height="100" HorizontalAlignment="Right"/> </Grid> |
06 TiggerAction 그룹
액션 대상을 자기 자신으로 설정
ControlStoryboardAction
Storyboard를 제어하기 위한 액션, storyboard를 XAML에서 시작하거나 종료 가능
Storyboard는 애니메이션 관련된 부분으로 애니메이션 과정에서 설명
ControlStoryboardOption: storyboard를 조작하는 방법을 의미
Storyboard: 조작할 storyboard의 이름을 의미
<Grid x:Name="LayoutRoot" Width="400"> <Grid.Resources> <Storyboard x:Key="Storyboard1"> <DoubleAnimation Storyboard.TargetName="rect1" Storyboard.TargetProperty="Width" To="200"/> </Storyboard> </Grid.Resources> <Button Content="ControlStoryboard" Width="140" Height="100" HorizontalAlignment="Left"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <im:ControlStoryboardAction ControlStoryboardOption="Play" Storyboard="{StaticResource Storyboard1}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Rectangle x:Name="rect1" Fill="Red" Width="100" Height="100" HorizontalAlignment="Right"/> </Grid> |
HyperlinkAction
특정 uri로 이동하기 위해 사용하는 액션
NavigateUri: HyperlinkAction에 의해 이동할 Uri를 의미
TargetWindow: 새롭게 이동하는 페이지를 새 창에 띄울 것인지(_blank), 현재 윈도우를 이동할 것 인지(_self), 또는 특정 윈도우(윈도우 이름)를 이동할 것인지 선택
<Grid x:Name="LayoutRoot" Width="400"> <Button Content="HyperlinkAction" Width="140" Height="100"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ic:HyperlinkAction NavigateUri="http://www.daum.net" TargetWindow="_blank"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> |
07 PlaySoundAction
오디오 파일을 재생하기 위해 사용하는 액션
Source: 재생될 오디오 파일의 경로를 의미
Volume: 소리의 크기를 의미(0~1)
<Grid x:Name="LayoutRoot" Width="400"> <Button Content="HyperlinkAction" Width="400" Height="100"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <im:PlaySoundAction Source="http://antasis9.woweb.net/silverlight/sound.wma" Volume="100"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> |
08 비헤이비어
컨트롤에 '행동'을 추가하는 기능
기본적으로 두가지의 비헤이비어를 제공
FluidMoveBehavior: 컨트롤의 위치가 변경될 때 애니메이션을 통해 부드럽게 움직이도록 함
Duration: 컨트롤이 움직이는 시간을 의미
EaseX: X좌표 이동 시 적용할 Easing Animation을 의미
EaseY: Y좌표 이동 시 적용할 Easing Animation을 의미
<Grid x:Name="LayoutRoot"> <Rectangle x:Name="Rect" Fill="Blue" Width="100" Height="100"> <i:Interaction.Behaviors> <il:FluidMoveBehavior/> </i:Interaction.Behaviors> </Rectangle> </Grid> |
public MainPage() { InitializeComponent();
Rect.MouseLeftButtonDown += new MouseButtonEventHandler(Rect_MouseLeftButtonDown); }
void Rect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Rect.Width += 100; } |
MouseDragElementBehavior
마우스 드래그로 컨트롤을 이동할 수 있게함
ConstrainToParentBounds: 컨트롤이 부모 컨트롤 밖으로 이동할 수 있는지 여부를 나타냄
X: 현재 컨트롤의 X좌표
Y: 현재 컨트롤의 Y좌표
<Grid x:Name="LayoutRoot" Background="Khaki" Width="600" Height="400"> <Rectangle Fill="Blue" Width="100" Height="100"> <i:Interaction.Behaviors> <il:MouseDragElementBehavior ConstrainToParentBounds="False" X="0" Y="0"/> </i:Interaction.Behaviors> </Rectangle> </Grid> |
출처: 실버라이트 3책