■ Binding 태그 확장의 ElementName 속성을 사용해 특정 엘리먼트 속성을 바인딩하는 방법을 보여준다. ▶ DoubleToDecimalValueConveter.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
using System; using System.Globalization; using System.Windows.Data; namespace TestProject { /// <summary> /// 실수↔10진수 값 변환자 /// </summary> [ValueConversion(typeof(double), typeof(decimal))] public class DoubleToDecimalValueConverter : IValueConverter { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 변환하기 - Convert(sourceValue, targetType, parameter, cultureInfo) /// <summary> /// 변환하기 /// </summary> /// <param name="sourceValue">값</param> /// <param name="targetType">타겟 타입</param> /// <param name="parameter">파라미터</param> /// <param name="cultureInfo">CultureInfo</param> /// <returns>변환 값</returns> public object Convert(object sourceValue, Type targetType, object parameter, CultureInfo cultureInfo) { decimal targetValue = new decimal((double)sourceValue); if(parameter != null) { targetValue = decimal.Round(targetValue, int.Parse(parameter as string)); } return targetValue; } #endregion #region 역변환하기 - ConvertBack(sourceValue, targetType, parameter, cultureInfo) /// <summary> /// 역변환하기 /// </summary> /// <param name="sourceValue">소스 값</param> /// <param name="targetType">타겟 타입</param> /// <param name="parameter">파라미터</param> /// <param name="cultureInfo">CultureInfo</param> /// <returns>역변환 값</returns> public object ConvertBack(object sourceValue, Type targetType, object parameter, CultureInfo cultureInfo) { return decimal.ToDouble((decimal)sourceValue); } #endregion } } |
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TestProject" Width="800" Height="600" Title="Binding 태그 확장 : ElementName 속성을 사용해 특정 엘리먼트 속성 바인딩하기" FontFamily="나눔고딕코딩" FontSize="16"> <Window.Resources> <local:DoubleToDecimalValueConverter x:Key="DoubleToDecimalValueConverterKey" /> </Window.Resources> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <ScrollBar Name="scrollBar" HorizontalAlignment="Center" Margin="10" Width="500" Height="20" Orientation="Horizontal" Maximum="100" SmallChange="1" LargeChange="10" /> <Label HorizontalAlignment="Center" Margin="10" Content="{Binding ElementName=scrollBar, Path=Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DoubleToDecimalValueConverterKey}, ConverterParameter=2}" /> </StackPanel> </Window> |
TestProject.zip
■ BlockUIContainer 엘리먼트를 사용하는 방법을 보여준다. ▶ 예제 코드 (XAML)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
<FlowDocument> ... <BlockUIContainer> <Polygon Points="144 48, 200 222, 53 114, 235 114, 88 222" Stroke="Blue" StrokeThickness="5"> <Polygon.Fill> <LinearGradientBrush StartPoint="0 0" EndPoint="1 0"> <GradientStopCollection> <GradientStop Offset="0" Color="Red" /> <GradientStop Offset="0.5" Color="Green" /> <GradientStop Offset="1" Color="BLue" /> </GradientStopCollection> </LinearGradientBrush> </Polygon.Fill> </Polygon> </BlockUIContainer> ... </FlowDocument> |
※ BlockUIContainer 엘리먼트는 UIElement 타입 객체를 포함할 수 있다.
■ FlowDocumentReader 엘리먼트를 사용하는 방법을 보여준다. ▶ 예제 코드 (XAML)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="프로그램 개요"> <FlowDocumentReader> <FlowDocument> <Paragraph Style="{StaticResource Header}">Program Overview</Paragraph> <Paragraph>This file presents an overview of the program.</Paragraph> <Paragraph> The description is probably several paragraphs in length. Perhaps it makes reference to the <Hyperlink NavigateUri="FileMenu.xaml">File Menu</Hyperlink> and <Hyperlink NavigateUri="HelpMenu.xaml">Help Menu</Hyperlink>. </Paragraph> </FlowDocument> </FlowDocumentReader> </Page> |
■ Hyperlink 엘리먼트의 TargetName/NavigateUri 속성을 사용해 페이지를 이동하는 방법을 보여준다. ▶ 예제 코드 (XAML)
|
<Hyperlink TargetName="frame" NavigateUri="Chapter02.xaml"> Chapter II </Hyperlink> |
※ frame는 Frame 타입이다.
■ x:TypeArguments 속성을 사용해 제너릭 타입 인자를 지정하는 방법을 보여준다. ▶ List (XAML)
|
(XAML)"><src:List x:TypeArguments="s:String" /> |
▶ Dictionary (XAML)
|
(XAML)"><src:Dictionary x:TypeArguments="s:String,s:String" /> |
▶ Queue (XAML)
|
(XAML)"><src:Queue x:TypeArguments="s:String,s:String" /> |
■ InkCanvas 객체의 데이터를 XAML 데이터로 변환해 저장하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
using System.IO; using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Markup; using System.Windows.Media; #region XAML 데이터 저장하기 - SaveXAMLData(inkCanvas, filePath) /// <summary> /// XAML 데이터 저장하기 /// </summary> /// <param name="inkCanvas">InkCanvas 객체</param> /// <param name="filePath">파일 경로</param> public void SaveXAMLData(InkCanvas inkCanvas, string filePath) { FileStream stream = null; try { stream = new FileStream(filePath, FileMode.Create, FileAccess.Write); DrawingGroup drawingGroup = new DrawingGroup(); foreach(Stroke stroke in inkCanvas.Strokes) { Color color = stroke.DrawingAttributes.Color; if(stroke.DrawingAttributes.IsHighlighter) { color = Color.FromArgb(128, color.R, color.G, color.B); } drawingGroup.Children.Add ( new GeometryDrawing ( new SolidColorBrush(color), null, stroke.GetGeometry() ) ); } XamlWriter.Save(drawingGroup, stream); } finally { if(stream != null) { stream.Close(); } } } #endregion |
■ InkCanvas 클래스의 Strokes 속성을 사용해 ISF 데이터를 파일에 저장하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
using System.IO; using System.Windows.Controls; #region 데이터 저장하기 - SaveISFData(inkCanvas, filePath) /// <summary> /// 데이터 저장하기 /// </summary> /// <param name="inkCanvas">InkCanvas 객체</param> /// <param name="filePath">파일 경로</param> public void SaveISFData(InkCanvas inkCanvas, string filePath) { FileStream fileStream = null; try { fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write); inkCanvas.Strokes.Save(fileStream); } finally { if(fileStream != null) { fileStream.Close(); } } } #endregion |
■ 파일에서 데이터를 로드하고 InkCanvas 클래스의 Strokes 속성에 값을 설정하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
using System.IO; using System.Windows.Controls; #region 데이터 로드하기 - LoadData(inkCanvas, filePath) /// <summary> /// 데이터 로드하기 /// </summary> /// <param name="inkCanvas">InkCanvas 객체</param> /// <param name="filePath">파일 경로</param> public void LoadData(InkCanvas inkCanvas, string filePath) { FileStream fileStream = null; try { fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); inkCanvas.Strokes = new StrokeCollection(fileStream); } finally { if(fileStream != null) { fileStream.Close(); } } } #endregion |
■ Tablet 클래스의 TabletDevices 속성을 사용해 Tablet 장치 설치 여부를 조사하는 방법을 보여준다. ▶ 예제 코드 (C#)
|
using System.Windows.Input; #region Tablet 장치 설치 여부 조사하기 - IsTableDeviceInstalled() /// <summary> /// Tablet 장치 설치 여부 조사하기 /// </summary> /// <returns>Tablet 장치 설치 여부</returns> public bool IsTableDeviceInstalled() { return Tablet.TabletDevices.Count > 0; } #endregion |
■ ResourceDictionary 엘리먼트를 사용해 리소스를 병합하는 방법을 보여준다. 동일한 키가 존재하는 경우, 메인 리소스 사전에 해당 리소스가 있으면 우선적으로 참조된다. 메인 리소스
더 읽기
■ StaticResource 태그 확장에서 x:Static 태그 확장을 사용해 시스템 리소스를 사용하는 방법을 보여준다. ▶ 예제 코드 (XAML)
|
Foreground="{StaticResource {x:Static SystemColors.ActiveCaptionBrushKey}}" |
■ x:Key 속성에서 x:Static 태그 확장을 사용해 시스템 리소스를 재정의하는 방법을 보여준다. ▶ 예제 코드 (XAML)
|
<StackPanel> <StackPanel.Resources> <SolidColorBrush x:Key="{x:Static SystemColors.ActiveCaptionBrushKey}" Color="Red" /> </StackPanel.Resources> <Button HorizontalAlignment="Center" VerticalAlignment="Center" Margin="24" Foreground="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}"> Button with Red text </Button> </StackPanel> |
■ DynamicResource 태그 확장을 사용해 정적 속성 값을 참조하는 방법을 보여준다. ▶ 예제 코드 (XAML)
|
<Label Foreground="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}"> Test </Label> |
■ DynamicResource 엘리먼트를 사용해 정적 속성 값을 참조하는 방법을 보여준다. ▶ 예제 코드 (XAML)
|
... <Label.Foreground> <DynamicResource> <DynamicResource.ResourceKey> <x:Static Member="SystemColors.ActiveCaptionBrushKey" /> </DynamicResource.ResourceKey> </DynamicResource> </Label.Foreground> ... |
■ StaticResource 태그 확장을 사용해 리소스를 사용하는 방법을 보여준다. ▶ 예제 코드 (XAML)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib"> <StackPanel.Resources> <s:Double x:Key="FontSizeKey"> 20 </s:Double> </StackPanel.Resources> <Button HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10" FontSize="{StaticResource FontSizeKey}"> 테스트 </Button> </StackPanel> |
■ StaticResource 엘리먼트를 사용해 리소스를 사용하는 방법을 보여준다. ▶ 예제 코드 (XAML)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib"> <StackPanel.Resources> <s:Double x:Key="FontSizeKey"> 20 </s:Double> </StackPanel.Resources> <Button HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10"> <Button.FontSize> <StaticResource ResourceKey="FontSizeKey" /> </Button.FontSize> 테스트 </Button> </StackPanel> |
■ x:Static 엘리먼트를 사용해 SystemParameters 클래스의 CaptionHeight 정적 속성 값을 참조하는 방법을 보여준다. ▶ 예제 코드 (C#)
|
<Button> <Button.Height> <x:Static Member="SystemParameters.CaptionHeight" /> </Button.Height> Test </Button> |
■ x:Static 태그 확장을 사용해 SystemParameters 클래스의 CaptionHeight 정적 속성 값을 참조하는 방법을 보여준다. ▶ 예제 코드 (XAML)
|
<Button Height="{x:Static SystemParameters.CaptionHeight}"> Test </Button> |
■ XAML 속성성 값 설정시 태그 확장 적용을 방지하는 방법을 보여준다. ▶ 예제 코드 (XAML)
|
<TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" FontSize="20" Text="{}{just a little text in herel}" /> |
■ ResourceDictionary(또는 다른 프레임워크의 유사한 사전 개념)의 각 리소스에 대한 고유한 키를 설정하는 방법을 보여준다. ▶ 예제 코드 (XAML)
|
... <StackPanel.Resources> <s:Double x:Key="LargeFontSizeDoubleKey">18.7</s:Double> <s:Double x:Key="SmallFontSizeDoubleKey">14.7</s:Double> </StackPanel.Resources> ... |
■ XAML 속성 값 설정시 값의 단위를 설정하는 방법을 보여준다. ▶ 사용 가능 단위 (XAML)
|
인치("in"), 센티미터("cm"), 포인트("pt"), 픽셀("px") Width="1.51in" Width="3.81cm" Width="108pt" ※ 단위는 대소문자 구분없이 사용 가능하다. ※ 값과 단위 사이 공백이 있어도 된다. Width="1.51 in" Width="3.81 cm" Width="108 pt" |
▶ 과학적 표기법 (XAML)
▶
더 읽기
■ TextBox 클래스에서 탭 키를 누른 경우 탭 키 대신 공백 문자를 추가하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
using System.Windows; using System.Windows.Controls; using System.Windows.Input; /// <summary> /// 텍스트 박스 /// </summary> private TextBox textBox; /// <summary> /// 탭 공백 수 /// </summary> private int tabSpaceCount = 4; #region 프리뷰 키 다운시 처리하기 - OnPreviewKeyDown(e) /// <summary> /// 프리뷰 키 다운시 처리하기 /// </summary> /// <param name="e">이벤트 인자</param> protected override void OnPreviewKeyDown(KeyEventArgs e) { base.OnPreviewKeyDown(e); if(e.Source == this.textBox && e.Key == Key.Tab) { string insert = new string(' ', this.tabSpaceCount); int characterIndex = this.textBox.SelectionStart; int lineIndex = this.textBox.GetLineIndexFromCharacterIndex(characterIndex); if(lineIndex != -1) { int columnIndex = characterIndex - this.textBox.GetCharacterIndexFromLineIndex(lineIndex); insert = new string(' ', this.tabSpaceCount - columnIndex % this.tabSpaceCount); } this.textBox.SelectedText = insert; this.textBox.CaretIndex = this.textBox.SelectionStart + this.textBox.SelectionLength; e.Handled = true; } } #endregion |
■ TextBox 클래스의 GetCharacterIndexFromLineIndex 메소드를 사용해 현재 열의 인덱스를 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
using System.Windows.Controls; #region 현재 열 구하기 - GetCurrentColumn(textBox) /// <summary> /// 현재 열 구하기 /// </summary> /// <param name="textBox">텍스트 박스</param> /// <returns>현재 열</returns> public int GetCurrentColumn(TextBox textBox) { int index = this.textBox.SelectionStart; int line = this.textBox.GetLineIndexFromCharacterIndex(index); int column = index - this.textBox.GetCharacterIndexFromLineIndex(line); return column; } #endregion |
■ TextBox 클래스의 GetLineIndexFromCharacterIndex 메소드를 사용해 현재 줄의 인덱스를 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
using System.Windows.Controls; #region 현재 줄 구하기 - GetCurrentLine(textBox) /// <summary> /// 현재 줄 구하기 /// </summary> /// <param name="textBox">텍스트 박스</param> /// <returns>현재 줄</returns> public int GetCurrentLine(TextBox textBox) { int index = this.textBox.SelectionStart; int line = this.textBox.GetLineIndexFromCharacterIndex(index); return line; } #endregion |
■ x:Code 엘리먼트를 사용해 XAML에서 실행되는 C# 코드를 정의하는 방법을 보여준다. ▶ 예제 코드 (C#)
|
<x:Code> <![CDATA[ // C# 코드가 기술된다. ]]> </x:Code> |