WPF 멀티쓰레드, Dispatcher, Background Worker, WPF 트리거, WPF Trigger, WPF 컨텐트프로퍼티, 의존프로퍼티, 이벤트라우팅
WPF 멀티쓰레드 프로그래밍, Dispatcher, Background Workerhttps://www.youtube.com/watch?v=KfY6DqWtcqs&list=PLxU-iZCqT52Cmj47aKB1T-SxI33YL7rYS&index=5&t=17s1.5 WPF 멀티쓰레드 프로그래밍멀티쓰레드란 여러 개의 쓰레드가 동시에 특정 코…
ojc.asia
(C#, WPF동영상강좌)WPF이벤트, 이벤트의 라우팅(RoutedEvent), 버블링(Bubbling) 이벤트, 터널링(Tunneling) 이벤트 n 이벤트 라우팅은 “어떤 이벤트가 컨트롤의 하위 또는 상위로 전달되는 것”을 이야기 하며 WPF에서 광범위하게 이용되는 방법입니다. n 이벤트 라우팅은 세가지로 분류할 수 있는데 이벤트가 발생했을 때 현재 컨…
ojc.asia
1.5 WPF 멀티쓰레드 프로그래밍
멀티쓰레드란 여러 개의 쓰레드가 동시에 특정 코드블럭을 실행하는 것이다.
멀티쓰레드는 모든 부분에서 사용가능 하지만 채팅 프로그램처럼 내가 글을 쓰는 동안에 상대방이 글을 보내면 빠르게 반응해서 UI 화면에 그려야 하는 경우등에 주로 사용된다.
모든 WPF 프로그램은 최소한의 렌더링을 위한 백그라운드 쓰레드와 UI 스레드(UI 인터페이스 관리) 두개의 쓰레드로 기동된다. UI 스레드는 사용자 입력을 받고 화면을 그리고, 코드를 실행하고, 이벤트등을 처리한다.
WPF는 기본적으로 STA(Single Thread Apartment) 모델을 지원하는데 하나의 쓰레드는 전체 응용프로그램에서 실행되고 모든 WPF 객체를 소유하고 있고 TextBox같은 WPF UIElements 요소들은 쓰레드 선호도라는 것이 있어 다른 쓰레드와 상호작용 할 수 없다. (UI 컨트롤은 다른 쓰레드에서 업데이트 할 수가 없다.)
즉 화면을 그리는 쓰레드는 컨트롤들을 소유하고 다른 쓰레드에서는 직접 접근할 수 없도록 되어 있다. 이를 쓰레드 선호도라 한다.
WPF에서 멀티 쓰레드 처리를 위해서 Dispatcher를 이용할 수도 있고 Background Worker를 사용할 수도 있다.
1.5.1 Dispatcher를 이용한 WPF 멀티쓰레드 프로그래밍
모든 비주얼 객체(TextBox, Button등)는 DispatcherObject 클래스를 상속받고 있으며 DispatcherObject가 UI 쓰레드의 Dispatcher 를 얻을 수 있게 해준다. 결국 이 Dispatcher 때문에 다른 쓰레드에서 UI 컨트롤을 변경 할 수 없는 것이다.
TextBox 같은 컨트롤을 다른 쓰레드에서 수정하려면 Dispatcher를 통해서 해야 된다는 것이다.
Dispatcher는 System.Windows.Threading.Dispatcher 클래스의 인스턴스로 응용 프로그램 쓰레드를 소유(쓰레드에 속한 모든 개체를 소유)하고 작업 항목의 대기열을 관리하는데 각각의 우선 순위를 사용하여 FIFO (First In First Out) 방식으로 UI 작업을 실행한다. 새 스레드를 만들지 않는다. 즉 멀티 스레드가 아니다.
DispatcherObject 클래스의 멤버로는 다음과 같은 것이 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[속성] |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Dispatcher : Dispatcher를 가지고 온다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[메소드] |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
CheckAccess() : 코드가 객체를 사용할 수있는 스레드이면 true를 반환. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
VerifyAccess() : 코드가 객체를 사용하기 위해 올바른 스레드인지 판단. 가능하다면 아무 작업도 수행하지 않고 그렇지 않으면 "InvalidOperationException"을 발생시킴. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
WPF 응용프로그램에서 수시로 자주 호출한다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
GetType () : 현재 인스턴스의 유형을 가져온다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
하나의 쓰레드에서 UIElement를 만들면 Dispatcher도 만들어지는데 새로운 TextBox를 만들면 거기에 따라 Dispatcher 객체도 만들어 진다.
대부분의 UI 객체(TextBox등)는 DisplatcherObject에서 파생되는데 이것은 Dispatcher와 연결된 객체라고 보면 된다.
만약 잘못된 쓰레드가 UI객체에 접근하려고 하면 DispatcherObject의 VerifyAccess() 메소드가 “InvalidOperationException”을 던지도록 되어 있다. (WPF는 쓰레드의 잘못된 접근을 막기 위해 VerifyAccess 메소드를 자주 호출한다.)
아래 코드를 보자. (Invalid Operation Exception이 발생한다.)
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Thread thread = new Thread(Update); thread.Start(); } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void Update() { Thread.Sleep(TimeSpan.FromSeconds(5)); txtName.Text = "홍길동"; } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
위 코드를 Dispatcher를 사용하면 아래와 같이 재작성 할 수 있다.
(Dispatcher의 BeginInvoke를 사용하면 해당 메소드의 실행이 마무리 될 때까지 블록킹 된다.)
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void Update() { // Simulate some work taking place Thread.Sleep(TimeSpan.FromSeconds(5)); this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate() { txtName.Text = "홍길동"; } ); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//this.Dispatcher.BeginInvoke(new Action(() => |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// { |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// TxtName.Text = "Hello Geeks !"; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// })); } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Dispatcher.BeginInvoke() 메서드는 두 개의 파라미터가 있는데 첫 번째는 작업의 우선 순위를 나타내고 두 번째는 매개변수는 실행할 코드가 있는 메소드를 가리키는 대리자(Delegate) 이다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
1.5.2 Background Worker를 이용한 WPF 멀티쓰레드 프로그래밍
Windows 응용 프로그램 멀티 쓰레딩에서 가장 어려운 개념은 다른 스레드에서 UI를 변경할 수 없다는 것이다. 대신 UI스레드에서 메소드를 호출해야 원하는 변경이 이루어 진다.
백그라운드 워커(Background Worker)는 System.ComponentModel 아래의 클래스로 코드를 별도의 쓰레드에서 동시에 비동기적으로 실행하게 해 주는데 응용프로그램의 기본 쓰레드와 자동으로 동기화 해준다. 호출 쓰레드는 정상적으로 실행이 되고 Background Worker는 백그라운드에서 비동기적으로 실행된다.
백그라운드에서 작업을 실행하고 UI 실행등을 연기하는데 사용되는데 사용자는 UI가 계속 반응하기를 원하면서 데이터를 다운로드 한다든지, 오래 걸리는 작업이 있어 진행사항을 표시해야 되는 경우, 데이터베이스 트랜잭션 처리 등에 유용하다.
Background Worker에서 일어나는 작업에 대해 변경이 생길 때 호출되는 ProcessedChanged 이벤트, 작업이 완료되었을 때 무언가를 할 수 있도록 지원하는 RunWorkerCompledted 이벤트가 발생한다.
DoWork 이벤트에서 백그라운드 쓰레드가 할일을 기술하는데 DoWork 이벤트 처리 메소드 내용은 다른 백그라운드 다른 쓰레드에서 처리되므로 UI쪽을 접근할 수 없는데 ReportProgress() 메소드를 호출하면 ProcessChanged 이벤트가 발생하여 UI를 업데이트하는 것이 가능하다.
ProgressChanged 및 RunWorkerCompleted 이벤트는 BackgroundWorker가 만들어지는 것과 동일한 스레드에서 실행된다.
BackgroundWorker는 일반적으로 기본/UI 쓰레드이므로 UI를 업데이트 할 수 있다. 따라서 실행중인 백그라운드 작업과 UI간에 수행 할 수있는 유일한 통신방법은 ReportProgress() 메서드를 사용하는 것이다.
DoWork 이벤트 처리 메소드 내부에서 파라미터가 필요하면 백그라운드 워커를 호출하는 RunWorkerAsync() 메소드의 인수로 넣어주면 된다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
int count = (int)e.Argument; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
DoWork 이벤트 처리 메소드 내부에서 e.Result 등으로 어떤 결과값을 넣어두면 RunWorkerCompledted 이벤트 처리 메소드에서 e.Result 형태로 꺼내볼 수 있다.
1.5.3 Background Worker를 이용한 WPF 멀티쓰레드 프로그래밍 실습
[간단히 Backgroud Worker를 사용한 예제를 작성해 보자.]
숫자를 입력하면 백그라운드 워커를 통해 ProgressBar에 진행 사항을 표시하고, 리스트 박스에 짝수들을 출력, 그리고 합을 구해 출력하는 예제이다.
1. BackgroundWorkerTest 하는 이름으로 WPF 프로젝트 생성

사진 설명을 입력하세요.
MainWindow.xaml 파일을 더블클릭 후 디자인 화면에서 아래와 같이 디자인 하자.
Label (Content 속성 : “숫자를 입력하세요”)
TextBox (Name 속성 : txtNumber, Text 속성 : “”)
Button(Name 속성 : btnStart, Text 속성 : “실행”)
Button(Name 속성 : btnCancel, Text 속성 : “중단”)
ProgressBar(Name 속성 : progressBar)
ListBox(Name 속성 : lstNumber)
Label(Content 속성 : “합계는”)
TextBlock(Name 속성 : tblkSum, Text 속성 “”)


MainWindow.xaml.cs
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Window x:Class="BackgroundWorkerTest.MainWindow" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
xmlns:local="clr-namespace:BackgroundWorkerTest" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
mc:Ignorable="d" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Title="MainWindow" Height="350" Width="359.844"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Grid> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Label Content="숫자를 입력하세요." HorizontalAlignment="Left" Margin="44,25,0,0" VerticalAlignment="Top" Width="121"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<TextBox x:Name="txtNumber" HorizontalAlignment="Left" Height="23" Margin="170,29,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="54"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Button x:Name="btnStart" Content="실행" HorizontalAlignment="Left" Margin="235,29,0,0" VerticalAlignment="Top" Width="44" Height="23" Click="btnStart_Click"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Button x:Name="brnCancel" Content="중단" HorizontalAlignment="Left" Margin="284,29,0,0" VerticalAlignment="Top" Width="41" Height="23" Click="btnCancel_Click"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<ProgressBar x:Name="progressBar" HorizontalAlignment="Left" Height="18" Margin="57,80,0,0" VerticalAlignment="Top" Width="268"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<ListBox x:Name="lstNumber" HorizontalAlignment="Left" Height="174" Margin="57,125,0,0" VerticalAlignment="Top" Width="100"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Label Content="합계는 ?" HorizontalAlignment="Left" Margin="194,125,0,0" VerticalAlignment="Top" Width="108"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<TextBlock x:Name="tblkSum" HorizontalAlignment="Left" Margin="202,151,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="77" Height="20" Foreground="#FFFAF8F8"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<TextBlock.Background> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<GradientStop Color="Black" Offset="0"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<GradientStop Color="#FFB1A5A5" Offset="1"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</LinearGradientBrush> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</TextBlock.Background> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<TextBlock.OpacityMask> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<GradientStop Color="Black" Offset="0"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<GradientStop Color="White" Offset="1"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</LinearGradientBrush> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</TextBlock.OpacityMask> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</TextBlock> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</Grid> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</Window> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
MainWindow.xaml.cs
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.ComponentModel; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Windows; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Threading; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Windows.Threading; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
namespace BackgroundWorkerTest |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public partial class MainWindow : Window |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//백그라운드 워커 선언 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private BackgroundWorker myThread; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//짝수의 합을 저장할 인스턴스 변수 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
int sum = 0; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public MainWindow() |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
InitializeComponent(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
protected override void OnInitialized(EventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
base.OnInitialized(e); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//백그라운드 워커 초기화 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업의 진행율이 바뀔때 ProgressChanged 이벤트 발생여부 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업취소 가능여부 true로 설정 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread = new BackgroundWorker() |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
WorkerReportsProgress = true, |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
WorkerSupportsCancellation = true |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
}; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//백그라운드에서 실행될 콜백 이벤트 생성 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//For the performing operation in the background. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//해야할 작업을 실행할 메소드 정의 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.DoWork += myThread_DoWork; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//UI쪽에 진행사항을 보여주기 위해 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//WorkerReportsProgress 속성값이 true 일때만 이벤트 발생 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.ProgressChanged += myThread_ProgressChanged; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업이 완료되었을 때 실행할 콜백메소드 정의 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.RunWorkerCompleted += myThread_RunWorkerCompleted; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
MessageBox.Show("Worker 초기화"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//백그라운드 워커가 실행하는 작업 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//DoWork 이벤트 처리 메소드에서 lstNumber.Items.Add(i) 와 같은 코드를 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//직접 실행시키면 "InvalidOperationException" 오류발생 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void myThread_DoWork(object sender, DoWorkEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
int count = (int)e.Argument; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
for (int i = 1; i <= count ; i++) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (myThread.CancellationPending) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
e.Cancel = true; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
return; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
else |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Thread.Sleep(100); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
(ThreadStart)delegate () |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (i % 2 == 0) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
sum += i; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
e.Result = sum; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
lstNumber.Items.Add(i); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.ReportProgress(i); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업의 진행률이 바뀔때 발생, ProgressBar에 변경사항을 출력 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//대체로 현재의 진행상태를 보여주는 코드 여기에 작성. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void myThread_ProgressChanged(object sender, ProgressChangedEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
progressBar.Value = e.ProgressPercentage; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업완료 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void myThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (e.Cancelled) MessageBox.Show("작업 취소..."); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
else if (e.Error != null) MessageBox.Show("에러발생..." + e.Error); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
else |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
tblkSum.Text = ((int)e.Result).ToString(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
MessageBox.Show("작업 완료!!"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void btnStart_Click(object sender, RoutedEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
int num; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (!int.TryParse(txtNumber.Text, out num)) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
MessageBox.Show("숫자를 입력하세요.!"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
return; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
progressBar.Maximum = num; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
lstNumber.Items.Clear(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.RunWorkerAsync(num); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void btnCancel_Click(object sender, RoutedEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.CancelAsync(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
WPF 트리거(Trigger), 이벤트 트리거(EventTrigger), ColorAnimation, DoubleAnimation, DoubleAnimationUsingKeyFra
n 발생하는 이벤트에 대한 액션을 정의한다.
n Trigger 또는 MultiTrigger는 특정 속성값이 변했을 때, DataTrigger, MultiDataTrigger는 바인딩 되는 값이 변경 되었을 때 발생하는 트리거이지만 EventTrigger는 특정 이벤트가 일어 났을때 트리거가 실행되며 FrameworkElement의 RoutedEvent가 발생했을 때 실행되는 트리거 이다.
n EventTrigger는 특정 이벤트가 발생했을 때 컨트롤이나 엘리먼트의 변경을 유도하는데 주로 그래픽 애니메이션등에서 사용되며FrameworkElement도 Triggers라는 프로퍼티를 정의하며 이 컬렉션에 들어갈 수 있는 유일한 Trigger가 EventTrigger이다.
n WPF의 라우팅 이벤트는 자식의 이벤트가 부모에게 전달되거나 부모가 먼저 이벤트를 가로챈 후 자식으로 전달 또는 해당 요소에서만 이벤트가 발생하도록 할 수 있는데 이벤트 트리거는 지정한 라우팅 이벤트가 발생할 때 할 일을 정의한다.
n 마우스 포인터가 특정 컨트롤 위에 있을 때의 애니메이션을 정의할 때 주로 이벤트 트리거를 사용하는데 이벤트 트리거는 상태의 종료에 대한 개념이 없으므로 이벤트를 발생시킨 조건이 종료하더라고 작업의 실행이 취소되지는 않으므로 이벤트 트리거를 사용할 때 컨트롤의 고유한 동작을 방해하지 않는 이벤트를 선택해야 한다.
n 예를들어 Button에 스타일을 정의하고 MouseDown 이벤트를 이벤트 트리거의 RoutedEvent로 설정 하더라도 해당 이벤트가 Button에서 먼저 처리 되므로 이벤트 트리거는 작동하지 않는다. 그러므로 대신 PreviewMouseDown등에서 사용해야 한다.
n 데이터 바인딩을 사용할 때 TargetUpdated 이벤트를 사용하는 경우 발생할 이벤트에 대해 바인딩 개체의 NotifyTargetUpdated 값을 true로 설정해야 한다.
n 이벤트 트리거는 스타일의 Triggers 속성 내에 하나 이상의 EventTrigger 요소를 추가하는데 트리거를 발생시키는 라우팅 이벤트 이름을 지정하는 RoutedEvent 속성 값을 설정해야 한다.
n ColorAnimation : UIElement의 컬러 프로퍼티(SolidColorBrush, LinearGradientBrush) 변화에 사용되는 애니메이션으로 Duration으로 시:분:초를 정의하고 From(source), To(target) 등의 속성등을 지정할 수 있다.
n StoryBoard는 UIElement의 속성에 애니메이션을 제공하기 의해 사용되고 TargetName과 TargetProperty 속성을 제공한다. TargetName은 애니메이션이 제공되는 컨트롤이며 TargetProperty는 컨트롤의 속성이다.
n [MainWindow.xaml]
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Border Name="border1" Width="100" Height="30" BorderBrush="Black" BorderThickness="1"> <Border.Background> <SolidColorBrush x:Name="MyBorder" Color="LightBlue" /> </Border.Background> <Border.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <BeginStoryboard> <Storyboard> <ColorAnimation Duration="0:0:1" Storyboard.TargetName="MyBorder" Storyboard.TargetProperty="Color" To="Gray" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Border.Triggers> </Border> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n DoubleAnimation : UIElement의 width/height 값을 변경하기 위해 사용.
n 아래 예문은 Border의 width는 5초동안 100에서 20까지 애니메이션 된다. 그리고 AutoReverse 속성 때문에 즉시 20에서 100으로 돌아오게 된다. AutoReverse 속성은 From à To à From의 형태를 지원하는 속성이다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Border Name="EventTriggerBorder" Width="100" Height="30" Background="Olive" BorderBrush="Black" BorderThickness="1"> <Border.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <BeginStoryboard> <Storyboard> <DoubleAnimation AutoReverse="True" Duration="0:0:2" From="1" Storyboard.TargetName="EventTriggerBorder" Storyboard.TargetProperty="(Border.Opacity)" To="0.5" /> <DoubleAnimation AutoReverse="True" Duration="0:0:5" From="100" Storyboard.TargetName="EventTriggerBorder" Storyboard.TargetProperty="(Border.Width)" To="20" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Border.Triggers> </Border> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n DoubleAnimationUsingKeyFrames : UIElement의 width/height 값을 변경하기 위해 사용하는 DoubleAnumation과 유사하며 추가적으로 KeyFrames 속성이 추가되었으며 두 개 이상의 대상 값을 사용하여 애니메이션을 만들 수 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Storyboard x:Key="LoadStoryBoard" AutoReverse="True" RepeatBehavior="Forever"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="LoadedBorder" Storyboard.TargetProperty="(UIElement.Opacity)"> <!— KeyTime은 Value에 도달하는 시간을 정의 à <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0.4" /> </DoubleAnimationUsingKeyFrames> </Storyboard> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
위 예문에서 Border의 투명도는 1에서 0.4까지 0.7초 동안 변경되며 RepeatBehavor 속성은 프로퍼티의 값을 기준으로 애니메이션을 반복할 때 사용하며 StoryBoard를 시작하기 위해서는 컨트롤의 EventTrigger 안에서 BeginStoryBoard 액션을 호출해야 한다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Border.Triggers> <EventTrigger RoutedEvent="FrameworkElement.Loaded"> <BeginStoryboard Storyboard="{StaticResource LoadStoryBoard}" /> </EventTrigger> </Border.Triggers> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n 아래 예문은 텍스트 박스가 포커스를 얻거나 잃을 때 텍스트 박스의 배경색을 간단한 애니메이션으로 구현한 예문이다.

사진 설명을 입력하세요.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Window x:Class="WpfApp6.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:WpfApp6" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <Style x:Key="NameBox" TargetType="TextBox"> <Setter Property="Background" Value="AntiqueWhite"/> <Setter Property="Margin" Value="5 0 5 5"/> <Style.Triggers> <EventTrigger RoutedEvent="GotFocus"> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetProperty="Background.Color" To="Gold" Duration="0:0:1" AutoReverse="True"/> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="LostFocus"> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetProperty="Background.Color" To="AntiqueWhite" Duration="0:0:1" AutoReverse="True"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Style.Triggers> </Style> <Style x:Key="ButtonStyle" TargetType="Button"> <Setter Property="HorizontalAlignment" Value="Right"/> <Setter Property="Margin" Value="0 10 5 0"/> <Setter Property="Width" Value="100"/> </Style> </Window.Resources> <StackPanel> <Label Content="First Name" /> <TextBox Style="{StaticResource NameBox}"/> <Label Content="Last Name" /> <TextBox Style="{StaticResource NameBox}"/> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> <Button Style="{StaticResource ButtonStyle}">OK</Button> <Button Style="{StaticResource ButtonStyle}">Cancel</Button> </StackPanel> </StackPanel> </Window> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
WPF 프로퍼티 개요 및 컨텐트 프로퍼티
WPF 객체, 엘리먼트들은 프로퍼티를 가지고 있는데 이것에 속성값을 부여해서 요소의 상태를 표현할 수 있다.
다음 XAML 코드는 버튼을 표시하고 세 개의 프로퍼티 값을 설정하고 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Button Foreground="LightSeaGreen" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
FontSize="20 pt" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Content="Click Me!" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
아래와 같은 “프로퍼티 엘리먼트”로도 표현 가능하다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Content="Click Me!"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
LightSeaGreen |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
ForeGround="LightSeaGreen"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Click Me! |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
아래처럼 Button.Content 태그는 생략 가능하다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
ForeGround="LightSeaGreen"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Click Me! |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
다음과 같은 표현 역시 가능하다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
LightSeaGreen |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Click Me! |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
20 pt |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
컨텐트 프로퍼티는 본 바와 같이 좀 특별하다. XAML에서 ContentControl을 상속한 클래스는 컨텐트 프로퍼티로 인식되는 특별한 하나의 프로퍼티가 있는데 Button의 경우 컨텐트 프로퍼티는 “Content”이다.
컨텐트 프로퍼티로 인식되는 프로퍼티는 System.Window.Serialization 네임스페이스에 정의된 ContentProperty Attribute에 의해 정의된다. PresentationFramework.dll 파일에 Button 클래스는 다음과 같이 정의되어 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[ContentPropery(“Content”)] //어트리뷰트 선언 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public class Button { } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
<Button> 태그 사이의 값을 Button의 Content 프로퍼티에 넣어 준다는 의미임.
StackPanel의 ContentProperty 어트리뷰트는 다음과 같이 정의되어 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[ContentPropery(“Children”)] //어트리뷰트 선언 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public class StackPanel { } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
이 ContentPropery 어트리뷰트는 StackPanel의 자식을 StackPanel 엘리먼트의 자식으로 포함하게 해준다. StackPanel 태그 사이의 요소들을 Children 프로퍼티에 넣어 준다는 이야기이다. 다음 예문을 보자.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Button 1 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Middle TextBlock |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Button 2 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
C# 코드에서 넣으려면 다음과 같이 하면 된다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
stackPanel.Children.Add(new Button |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Content=”Button 1” |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
}); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
…… |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
3.2 컨텐트 프로퍼티 덤프 예제
비주얼 스튜디오 -> WPF 응용프로그램 , 프로젝트명 : DumpContentProperty
App.xaml, MainWindow.xaml 삭제
추가 -> 새항목 -> C# 클래스, 이름 : DumpContentProperty
생성 후 우측 솔루션 탐색기의 Properties 더블 클릭 후 출력형태를 콘솔 응용 프로그램으로 설정.

사진 설명을 입력하세요.
[DumpContentProperty.cs]
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Collections.Generic; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Reflection; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Windows; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Windows.Markup; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
namespace DumpContentProperty |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
class DumpContentProperty |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[STAThread] |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public static void Main() |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// PresentationCore, PresentationFramework 참조추가 되어 있어야 한다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
UIElement dummy1 = new UIElement(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
FrameworkElement dummy2 = new FrameworkElement(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// 클래스와 ContentProperty를 담을 SortedList 정의 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
SortedList<string, string> listClass = new SortedList<string, string>(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
string strFormat = "{0,-35}{1}"; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Loop through the loaded assemblies. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
foreach (AssemblyName asmblyname in |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Assembly.GetExecutingAssembly().GetReferencedAssemblies()) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Loop through the types. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
foreach (Type type in Assembly.Load(asmblyname).GetTypes()) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Loop through the custom attributes. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// (Set argument to 'false' for non-inherited only!) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
foreach (object obj in type.GetCustomAttributes( |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
typeof(ContentPropertyAttribute), true)) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Add to list if ContentPropertyAttribute. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (type.IsPublic && obj as ContentPropertyAttribute != null) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
listClass.Add(type.Name, |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
(obj as ContentPropertyAttribute).Name); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Display the results. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Console.WriteLine(strFormat, "Class", "Content Property"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Console.WriteLine(strFormat, "-----", "----------------"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
foreach (string strClass in listClass.Keys) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Console.WriteLine(strFormat, strClass, listClass[strClass]); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Console.ReadKey(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
[실행 결과]

사진 설명을 입력하세요.
WPF 멀티쓰레드, Dispatcher, Background Worker, WPF 트리거, WPF Trigger, WPF 컨텐트프로퍼티, 의존프로퍼티

WPF 프로퍼티 개요 및 컨텐트 프로퍼티WPF 객체, 엘리먼트들은 프로퍼티를 가지고 있는데 이것에 속성값을 부여해서 요소의 상태를 표현할 수 있다.다음 XAML 코드는 버튼을 표시하고 세 개의 프로퍼티 값을 설정하고 있다.<Button Foreground='LightSeaGreen'FontSize='20 pt'Content='Click Me!'/>…
ojc.asia

WPF 멀티쓰레드 프로그래밍, Dispatcher, Background Workerhttps://www.youtube.com/watch?v=KfY6DqWtcqs&list=PLxU-iZCqT52Cmj47aKB1T-SxI33YL7rYS&index=5&t=17s1.5 WPF 멀티쓰레드 프로그래밍멀티쓰레드란 여러 개의 쓰레드가 동시에 특정 코…
ojc.asia
1.5 WPF 멀티쓰레드 프로그래밍
멀티쓰레드란 여러 개의 쓰레드가 동시에 특정 코드블럭을 실행하는 것이다.
멀티쓰레드는 모든 부분에서 사용가능 하지만 채팅 프로그램처럼 내가 글을 쓰는 동안에 상대방이 글을 보내면 빠르게 반응해서 UI 화면에 그려야 하는 경우등에 주로 사용된다.
모든 WPF 프로그램은 최소한의 렌더링을 위한 백그라운드 쓰레드와 UI 스레드(UI 인터페이스 관리) 두개의 쓰레드로 기동된다. UI 스레드는 사용자 입력을 받고 화면을 그리고, 코드를 실행하고, 이벤트등을 처리한다.
WPF는 기본적으로 STA(Single Thread Apartment) 모델을 지원하는데 하나의 쓰레드는 전체 응용프로그램에서 실행되고 모든 WPF 객체를 소유하고 있고 TextBox같은 WPF UIElements 요소들은 쓰레드 선호도라는 것이 있어 다른 쓰레드와 상호작용 할 수 없다. (UI 컨트롤은 다른 쓰레드에서 업데이트 할 수가 없다.)
즉 화면을 그리는 쓰레드는 컨트롤들을 소유하고 다른 쓰레드에서는 직접 접근할 수 없도록 되어 있다. 이를 쓰레드 선호도라 한다.
WPF에서 멀티 쓰레드 처리를 위해서 Dispatcher를 이용할 수도 있고 Background Worker를 사용할 수도 있다.
1.5.1 Dispatcher를 이용한 WPF 멀티쓰레드 프로그래밍
모든 비주얼 객체(TextBox, Button등)는 DispatcherObject 클래스를 상속받고 있으며 DispatcherObject가 UI 쓰레드의 Dispatcher 를 얻을 수 있게 해준다. 결국 이 Dispatcher 때문에 다른 쓰레드에서 UI 컨트롤을 변경 할 수 없는 것이다.
TextBox 같은 컨트롤을 다른 쓰레드에서 수정하려면 Dispatcher를 통해서 해야 된다는 것이다.
Dispatcher는 System.Windows.Threading.Dispatcher 클래스의 인스턴스로 응용 프로그램 쓰레드를 소유(쓰레드에 속한 모든 개체를 소유)하고 작업 항목의 대기열을 관리하는데 각각의 우선 순위를 사용하여 FIFO (First In First Out) 방식으로 UI 작업을 실행한다. 새 스레드를 만들지 않는다. 즉 멀티 스레드가 아니다.
DispatcherObject 클래스의 멤버로는 다음과 같은 것이 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[속성] |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Dispatcher : Dispatcher를 가지고 온다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[메소드] |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
CheckAccess() : 코드가 객체를 사용할 수있는 스레드이면 true를 반환. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
VerifyAccess() : 코드가 객체를 사용하기 위해 올바른 스레드인지 판단. 가능하다면 아무 작업도 수행하지 않고 그렇지 않으면 "InvalidOperationException"을 발생시킴. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
WPF 응용프로그램에서 수시로 자주 호출한다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
GetType () : 현재 인스턴스의 유형을 가져온다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
하나의 쓰레드에서 UIElement를 만들면 Dispatcher도 만들어지는데 새로운 TextBox를 만들면 거기에 따라 Dispatcher 객체도 만들어 진다.
대부분의 UI 객체(TextBox등)는 DisplatcherObject에서 파생되는데 이것은 Dispatcher와 연결된 객체라고 보면 된다.
만약 잘못된 쓰레드가 UI객체에 접근하려고 하면 DispatcherObject의 VerifyAccess() 메소드가 “InvalidOperationException”을 던지도록 되어 있다. (WPF는 쓰레드의 잘못된 접근을 막기 위해 VerifyAccess 메소드를 자주 호출한다.)
아래 코드를 보자. (Invalid Operation Exception이 발생한다.)
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Thread thread = new Thread(Update); thread.Start(); } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void Update() { Thread.Sleep(TimeSpan.FromSeconds(5)); txtName.Text = "홍길동"; } } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
위 코드를 Dispatcher를 사용하면 아래와 같이 재작성 할 수 있다.
(Dispatcher의 BeginInvoke를 사용하면 해당 메소드의 실행이 마무리 될 때까지 블록킹 된다.)
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void Update() { // Simulate some work taking place Thread.Sleep(TimeSpan.FromSeconds(5)); this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate() { txtName.Text = "홍길동"; } ); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//this.Dispatcher.BeginInvoke(new Action(() => |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// { |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// TxtName.Text = "Hello Geeks !"; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// })); } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Dispatcher.BeginInvoke() 메서드는 두 개의 파라미터가 있는데 첫 번째는 작업의 우선 순위를 나타내고 두 번째는 매개변수는 실행할 코드가 있는 메소드를 가리키는 대리자(Delegate) 이다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
1.5.2 Background Worker를 이용한 WPF 멀티쓰레드 프로그래밍
Windows 응용 프로그램 멀티 쓰레딩에서 가장 어려운 개념은 다른 스레드에서 UI를 변경할 수 없다는 것이다. 대신 UI스레드에서 메소드를 호출해야 원하는 변경이 이루어 진다.
백그라운드 워커(Background Worker)는 System.ComponentModel 아래의 클래스로 코드를 별도의 쓰레드에서 동시에 비동기적으로 실행하게 해 주는데 응용프로그램의 기본 쓰레드와 자동으로 동기화 해준다. 호출 쓰레드는 정상적으로 실행이 되고 Background Worker는 백그라운드에서 비동기적으로 실행된다.
백그라운드에서 작업을 실행하고 UI 실행등을 연기하는데 사용되는데 사용자는 UI가 계속 반응하기를 원하면서 데이터를 다운로드 한다든지, 오래 걸리는 작업이 있어 진행사항을 표시해야 되는 경우, 데이터베이스 트랜잭션 처리 등에 유용하다.
Background Worker에서 일어나는 작업에 대해 변경이 생길 때 호출되는 ProcessedChanged 이벤트, 작업이 완료되었을 때 무언가를 할 수 있도록 지원하는 RunWorkerCompledted 이벤트가 발생한다.
DoWork 이벤트에서 백그라운드 쓰레드가 할일을 기술하는데 DoWork 이벤트 처리 메소드 내용은 다른 백그라운드 다른 쓰레드에서 처리되므로 UI쪽을 접근할 수 없는데 ReportProgress() 메소드를 호출하면 ProcessChanged 이벤트가 발생하여 UI를 업데이트하는 것이 가능하다.
ProgressChanged 및 RunWorkerCompleted 이벤트는 BackgroundWorker가 만들어지는 것과 동일한 스레드에서 실행된다.
BackgroundWorker는 일반적으로 기본/UI 쓰레드이므로 UI를 업데이트 할 수 있다. 따라서 실행중인 백그라운드 작업과 UI간에 수행 할 수있는 유일한 통신방법은 ReportProgress() 메서드를 사용하는 것이다.
DoWork 이벤트 처리 메소드 내부에서 파라미터가 필요하면 백그라운드 워커를 호출하는 RunWorkerAsync() 메소드의 인수로 넣어주면 된다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
int count = (int)e.Argument; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
DoWork 이벤트 처리 메소드 내부에서 e.Result 등으로 어떤 결과값을 넣어두면 RunWorkerCompledted 이벤트 처리 메소드에서 e.Result 형태로 꺼내볼 수 있다.
1.5.3 Background Worker를 이용한 WPF 멀티쓰레드 프로그래밍 실습
[간단히 Backgroud Worker를 사용한 예제를 작성해 보자.]
숫자를 입력하면 백그라운드 워커를 통해 ProgressBar에 진행 사항을 표시하고, 리스트 박스에 짝수들을 출력, 그리고 합을 구해 출력하는 예제이다.
1. BackgroundWorkerTest 하는 이름으로 WPF 프로젝트 생성

사진 설명을 입력하세요.
MainWindow.xaml 파일을 더블클릭 후 디자인 화면에서 아래와 같이 디자인 하자.
Label (Content 속성 : “숫자를 입력하세요”)
TextBox (Name 속성 : txtNumber, Text 속성 : “”)
Button(Name 속성 : btnStart, Text 속성 : “실행”)
Button(Name 속성 : btnCancel, Text 속성 : “중단”)
ProgressBar(Name 속성 : progressBar)
ListBox(Name 속성 : lstNumber)
Label(Content 속성 : “합계는”)
TextBlock(Name 속성 : tblkSum, Text 속성 “”)


MainWindow.xaml.cs
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Window x:Class="BackgroundWorkerTest.MainWindow" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
xmlns:local="clr-namespace:BackgroundWorkerTest" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
mc:Ignorable="d" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Title="MainWindow" Height="350" Width="359.844"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Grid> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Label Content="숫자를 입력하세요." HorizontalAlignment="Left" Margin="44,25,0,0" VerticalAlignment="Top" Width="121"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<TextBox x:Name="txtNumber" HorizontalAlignment="Left" Height="23" Margin="170,29,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="54"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Button x:Name="btnStart" Content="실행" HorizontalAlignment="Left" Margin="235,29,0,0" VerticalAlignment="Top" Width="44" Height="23" Click="btnStart_Click"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Button x:Name="brnCancel" Content="중단" HorizontalAlignment="Left" Margin="284,29,0,0" VerticalAlignment="Top" Width="41" Height="23" Click="btnCancel_Click"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<ProgressBar x:Name="progressBar" HorizontalAlignment="Left" Height="18" Margin="57,80,0,0" VerticalAlignment="Top" Width="268"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<ListBox x:Name="lstNumber" HorizontalAlignment="Left" Height="174" Margin="57,125,0,0" VerticalAlignment="Top" Width="100"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Label Content="합계는 ?" HorizontalAlignment="Left" Margin="194,125,0,0" VerticalAlignment="Top" Width="108"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<TextBlock x:Name="tblkSum" HorizontalAlignment="Left" Margin="202,151,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="77" Height="20" Foreground="#FFFAF8F8"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<TextBlock.Background> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<GradientStop Color="Black" Offset="0"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<GradientStop Color="#FFB1A5A5" Offset="1"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</LinearGradientBrush> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</TextBlock.Background> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<TextBlock.OpacityMask> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<GradientStop Color="Black" Offset="0"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<GradientStop Color="White" Offset="1"/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</LinearGradientBrush> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</TextBlock.OpacityMask> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</TextBlock> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</Grid> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
</Window> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
MainWindow.xaml.cs
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.ComponentModel; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Windows; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Threading; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Windows.Threading; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
namespace BackgroundWorkerTest |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public partial class MainWindow : Window |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//백그라운드 워커 선언 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private BackgroundWorker myThread; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//짝수의 합을 저장할 인스턴스 변수 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
int sum = 0; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public MainWindow() |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
InitializeComponent(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
protected override void OnInitialized(EventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
base.OnInitialized(e); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//백그라운드 워커 초기화 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업의 진행율이 바뀔때 ProgressChanged 이벤트 발생여부 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업취소 가능여부 true로 설정 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread = new BackgroundWorker() |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
WorkerReportsProgress = true, |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
WorkerSupportsCancellation = true |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
}; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//백그라운드에서 실행될 콜백 이벤트 생성 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//For the performing operation in the background. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//해야할 작업을 실행할 메소드 정의 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.DoWork += myThread_DoWork; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//UI쪽에 진행사항을 보여주기 위해 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//WorkerReportsProgress 속성값이 true 일때만 이벤트 발생 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.ProgressChanged += myThread_ProgressChanged; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업이 완료되었을 때 실행할 콜백메소드 정의 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.RunWorkerCompleted += myThread_RunWorkerCompleted; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
MessageBox.Show("Worker 초기화"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//백그라운드 워커가 실행하는 작업 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//DoWork 이벤트 처리 메소드에서 lstNumber.Items.Add(i) 와 같은 코드를 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//직접 실행시키면 "InvalidOperationException" 오류발생 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void myThread_DoWork(object sender, DoWorkEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
int count = (int)e.Argument; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
for (int i = 1; i <= count ; i++) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (myThread.CancellationPending) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
e.Cancel = true; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
return; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
else |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Thread.Sleep(100); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
(ThreadStart)delegate () |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (i % 2 == 0) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
sum += i; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
e.Result = sum; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
lstNumber.Items.Add(i); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.ReportProgress(i); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업의 진행률이 바뀔때 발생, ProgressBar에 변경사항을 출력 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//대체로 현재의 진행상태를 보여주는 코드 여기에 작성. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void myThread_ProgressChanged(object sender, ProgressChangedEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
progressBar.Value = e.ProgressPercentage; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
//작업완료 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void myThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (e.Cancelled) MessageBox.Show("작업 취소..."); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
else if (e.Error != null) MessageBox.Show("에러발생..." + e.Error); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
else |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
tblkSum.Text = ((int)e.Result).ToString(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
MessageBox.Show("작업 완료!!"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void btnStart_Click(object sender, RoutedEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
int num; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (!int.TryParse(txtNumber.Text, out num)) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
MessageBox.Show("숫자를 입력하세요.!"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
return; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
progressBar.Maximum = num; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
lstNumber.Items.Clear(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.RunWorkerAsync(num); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
private void btnCancel_Click(object sender, RoutedEventArgs e) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
myThread.CancelAsync(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
WPF 트리거(Trigger), 이벤트 트리거(EventTrigger), ColorAnimation, DoubleAnimation, DoubleAnimationUsingKeyFra
n 발생하는 이벤트에 대한 액션을 정의한다.
n Trigger 또는 MultiTrigger는 특정 속성값이 변했을 때, DataTrigger, MultiDataTrigger는 바인딩 되는 값이 변경 되었을 때 발생하는 트리거이지만 EventTrigger는 특정 이벤트가 일어 났을때 트리거가 실행되며 FrameworkElement의 RoutedEvent가 발생했을 때 실행되는 트리거 이다.
n EventTrigger는 특정 이벤트가 발생했을 때 컨트롤이나 엘리먼트의 변경을 유도하는데 주로 그래픽 애니메이션등에서 사용되며FrameworkElement도 Triggers라는 프로퍼티를 정의하며 이 컬렉션에 들어갈 수 있는 유일한 Trigger가 EventTrigger이다.
n WPF의 라우팅 이벤트는 자식의 이벤트가 부모에게 전달되거나 부모가 먼저 이벤트를 가로챈 후 자식으로 전달 또는 해당 요소에서만 이벤트가 발생하도록 할 수 있는데 이벤트 트리거는 지정한 라우팅 이벤트가 발생할 때 할 일을 정의한다.
n 마우스 포인터가 특정 컨트롤 위에 있을 때의 애니메이션을 정의할 때 주로 이벤트 트리거를 사용하는데 이벤트 트리거는 상태의 종료에 대한 개념이 없으므로 이벤트를 발생시킨 조건이 종료하더라고 작업의 실행이 취소되지는 않으므로 이벤트 트리거를 사용할 때 컨트롤의 고유한 동작을 방해하지 않는 이벤트를 선택해야 한다.
n 예를들어 Button에 스타일을 정의하고 MouseDown 이벤트를 이벤트 트리거의 RoutedEvent로 설정 하더라도 해당 이벤트가 Button에서 먼저 처리 되므로 이벤트 트리거는 작동하지 않는다. 그러므로 대신 PreviewMouseDown등에서 사용해야 한다.
n 데이터 바인딩을 사용할 때 TargetUpdated 이벤트를 사용하는 경우 발생할 이벤트에 대해 바인딩 개체의 NotifyTargetUpdated 값을 true로 설정해야 한다.
n 이벤트 트리거는 스타일의 Triggers 속성 내에 하나 이상의 EventTrigger 요소를 추가하는데 트리거를 발생시키는 라우팅 이벤트 이름을 지정하는 RoutedEvent 속성 값을 설정해야 한다.
n ColorAnimation : UIElement의 컬러 프로퍼티(SolidColorBrush, LinearGradientBrush) 변화에 사용되는 애니메이션으로 Duration으로 시:분:초를 정의하고 From(source), To(target) 등의 속성등을 지정할 수 있다.
n StoryBoard는 UIElement의 속성에 애니메이션을 제공하기 의해 사용되고 TargetName과 TargetProperty 속성을 제공한다. TargetName은 애니메이션이 제공되는 컨트롤이며 TargetProperty는 컨트롤의 속성이다.
n [MainWindow.xaml]
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Border Name="border1" Width="100" Height="30" BorderBrush="Black" BorderThickness="1"> <Border.Background> <SolidColorBrush x:Name="MyBorder" Color="LightBlue" /> </Border.Background> <Border.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <BeginStoryboard> <Storyboard> <ColorAnimation Duration="0:0:1" Storyboard.TargetName="MyBorder" Storyboard.TargetProperty="Color" To="Gray" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Border.Triggers> </Border> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n DoubleAnimation : UIElement의 width/height 값을 변경하기 위해 사용.
n 아래 예문은 Border의 width는 5초동안 100에서 20까지 애니메이션 된다. 그리고 AutoReverse 속성 때문에 즉시 20에서 100으로 돌아오게 된다. AutoReverse 속성은 From à To à From의 형태를 지원하는 속성이다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Border Name="EventTriggerBorder" Width="100" Height="30" Background="Olive" BorderBrush="Black" BorderThickness="1"> <Border.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <BeginStoryboard> <Storyboard> <DoubleAnimation AutoReverse="True" Duration="0:0:2" From="1" Storyboard.TargetName="EventTriggerBorder" Storyboard.TargetProperty="(Border.Opacity)" To="0.5" /> <DoubleAnimation AutoReverse="True" Duration="0:0:5" From="100" Storyboard.TargetName="EventTriggerBorder" Storyboard.TargetProperty="(Border.Width)" To="20" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Border.Triggers> </Border> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n DoubleAnimationUsingKeyFrames : UIElement의 width/height 값을 변경하기 위해 사용하는 DoubleAnumation과 유사하며 추가적으로 KeyFrames 속성이 추가되었으며 두 개 이상의 대상 값을 사용하여 애니메이션을 만들 수 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Storyboard x:Key="LoadStoryBoard" AutoReverse="True" RepeatBehavior="Forever"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="LoadedBorder" Storyboard.TargetProperty="(UIElement.Opacity)"> <!— KeyTime은 Value에 도달하는 시간을 정의 à <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0.4" /> </DoubleAnimationUsingKeyFrames> </Storyboard> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
위 예문에서 Border의 투명도는 1에서 0.4까지 0.7초 동안 변경되며 RepeatBehavor 속성은 프로퍼티의 값을 기준으로 애니메이션을 반복할 때 사용하며 StoryBoard를 시작하기 위해서는 컨트롤의 EventTrigger 안에서 BeginStoryBoard 액션을 호출해야 한다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Border.Triggers> <EventTrigger RoutedEvent="FrameworkElement.Loaded"> <BeginStoryboard Storyboard="{StaticResource LoadStoryBoard}" /> </EventTrigger> </Border.Triggers> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
n 아래 예문은 텍스트 박스가 포커스를 얻거나 잃을 때 텍스트 박스의 배경색을 간단한 애니메이션으로 구현한 예문이다.

사진 설명을 입력하세요.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Window x:Class="WpfApp6.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:WpfApp6" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <Style x:Key="NameBox" TargetType="TextBox"> <Setter Property="Background" Value="AntiqueWhite"/> <Setter Property="Margin" Value="5 0 5 5"/> <Style.Triggers> <EventTrigger RoutedEvent="GotFocus"> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetProperty="Background.Color" To="Gold" Duration="0:0:1" AutoReverse="True"/> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="LostFocus"> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetProperty="Background.Color" To="AntiqueWhite" Duration="0:0:1" AutoReverse="True"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Style.Triggers> </Style> <Style x:Key="ButtonStyle" TargetType="Button"> <Setter Property="HorizontalAlignment" Value="Right"/> <Setter Property="Margin" Value="0 10 5 0"/> <Setter Property="Width" Value="100"/> </Style> </Window.Resources> <StackPanel> <Label Content="First Name" /> <TextBox Style="{StaticResource NameBox}"/> <Label Content="Last Name" /> <TextBox Style="{StaticResource NameBox}"/> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> <Button Style="{StaticResource ButtonStyle}">OK</Button> <Button Style="{StaticResource ButtonStyle}">Cancel</Button> </StackPanel> </StackPanel> </Window> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
WPF 프로퍼티 개요 및 컨텐트 프로퍼티
WPF 객체, 엘리먼트들은 프로퍼티를 가지고 있는데 이것에 속성값을 부여해서 요소의 상태를 표현할 수 있다.
다음 XAML 코드는 버튼을 표시하고 세 개의 프로퍼티 값을 설정하고 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
<Button Foreground="LightSeaGreen" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
FontSize="20 pt" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Content="Click Me!" |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
/> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
아래와 같은 “프로퍼티 엘리먼트”로도 표현 가능하다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Content="Click Me!"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
LightSeaGreen |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
ForeGround="LightSeaGreen"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Click Me! |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
아래처럼 Button.Content 태그는 생략 가능하다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
ForeGround="LightSeaGreen"> |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Click Me! |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
다음과 같은 표현 역시 가능하다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
LightSeaGreen |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Click Me! |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
20 pt |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
컨텐트 프로퍼티는 본 바와 같이 좀 특별하다. XAML에서 ContentControl을 상속한 클래스는 컨텐트 프로퍼티로 인식되는 특별한 하나의 프로퍼티가 있는데 Button의 경우 컨텐트 프로퍼티는 “Content”이다.
컨텐트 프로퍼티로 인식되는 프로퍼티는 System.Window.Serialization 네임스페이스에 정의된 ContentProperty Attribute에 의해 정의된다. PresentationFramework.dll 파일에 Button 클래스는 다음과 같이 정의되어 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[ContentPropery(“Content”)] //어트리뷰트 선언 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public class Button { } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
<Button> 태그 사이의 값을 Button의 Content 프로퍼티에 넣어 준다는 의미임.
StackPanel의 ContentProperty 어트리뷰트는 다음과 같이 정의되어 있다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[ContentPropery(“Children”)] //어트리뷰트 선언 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public class StackPanel { } |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
이 ContentPropery 어트리뷰트는 StackPanel의 자식을 StackPanel 엘리먼트의 자식으로 포함하게 해준다. StackPanel 태그 사이의 요소들을 Children 프로퍼티에 넣어 준다는 이야기이다. 다음 예문을 보자.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Button 1 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Middle TextBlock |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Button 2 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
C# 코드에서 넣으려면 다음과 같이 하면 된다.
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
stackPanel.Children.Add(new Button |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Content=”Button 1” |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
}); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
…… |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
3.2 컨텐트 프로퍼티 덤프 예제
비주얼 스튜디오 -> WPF 응용프로그램 , 프로젝트명 : DumpContentProperty
App.xaml, MainWindow.xaml 삭제
추가 -> 새항목 -> C# 클래스, 이름 : DumpContentProperty
생성 후 우측 솔루션 탐색기의 Properties 더블 클릭 후 출력형태를 콘솔 응용 프로그램으로 설정.

사진 설명을 입력하세요.
[DumpContentProperty.cs]
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Collections.Generic; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Reflection; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Windows; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
using System.Windows.Markup; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
namespace DumpContentProperty |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
class DumpContentProperty |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
[STAThread] |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
public static void Main() |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// PresentationCore, PresentationFramework 참조추가 되어 있어야 한다. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
UIElement dummy1 = new UIElement(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
FrameworkElement dummy2 = new FrameworkElement(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// 클래스와 ContentProperty를 담을 SortedList 정의 |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
SortedList<string, string> listClass = new SortedList<string, string>(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
string strFormat = "{0,-35}{1}"; |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Loop through the loaded assemblies. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
foreach (AssemblyName asmblyname in |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Assembly.GetExecutingAssembly().GetReferencedAssemblies()) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Loop through the types. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
foreach (Type type in Assembly.Load(asmblyname).GetTypes()) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Loop through the custom attributes. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// (Set argument to 'false' for non-inherited only!) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
foreach (object obj in type.GetCustomAttributes( |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
typeof(ContentPropertyAttribute), true)) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
{ |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Add to list if ContentPropertyAttribute. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
if (type.IsPublic && obj as ContentPropertyAttribute != null) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
listClass.Add(type.Name, |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
(obj as ContentPropertyAttribute).Name); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
// Display the results. |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Console.WriteLine(strFormat, "Class", "Content Property"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Console.WriteLine(strFormat, "-----", "----------------"); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
foreach (string strClass in listClass.Keys) |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Console.WriteLine(strFormat, strClass, listClass[strClass]); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
Console.ReadKey(); |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
- 0열 선택0열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
} |
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
[실행 결과]

사진 설명을 입력하세요.
#WPF프로퍼티, #컨텐트프로퍼티. #WPF교육, #WPF강의, #WPF강좌, #WPF학원
WPF프로퍼티, 컨텐트프로퍼티. WPF교육, WPF강의, WPF강좌, WPF학원
#이벤트트리거, #WPF트리거, #데이터바인딩, #WPF데이터바인딩, #DataBinding, #WPF, #WPF강좌, #WPF교육, #WPF강의, #시샵, #닷넷, #Csharp, #XAML,
#WPF, #WPF멀티쓰레드, #Dispatcher, #BackgroundWorker
#WPF프로퍼티, #컨텐트프로퍼티. #WPF교육, #WPF강의, #WPF강좌, #WPF학원
WPF프로퍼티, 컨텐트프로퍼티. WPF교육, WPF강의, WPF강좌, WPF학원
#이벤트트리거, #WPF트리거, #데이터바인딩, #WPF데이터바인딩, #DataBinding, #WPF, #WPF강좌, #WPF교육, #WPF강의, #시샵, #닷넷, #Csharp, #XAML,
#WPF, #WPF멀티쓰레드, #Dispatcher, #BackgroundWorker
댓글 없음:
댓글 쓰기