찰스 페졸드의 WPF 를 읽으면서 정리한 폰트 선택 다이얼로그 박스(ChooseFont) 소스.
WPF에서 기본으로 제공되지 않는 폰트 선택 다이얼로그 박스를 구현한 소스.
이 소스를 기반으로 좀 더 미려한 폰트 선택 다이얼로그 박스를 만들 수 있을 것이다.
[ChooseFont.cs 파일]
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace ChooseFont
{
public class ChooseFont : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new ChooseFont());
}
public ChooseFont()
{
Title = "Choose Font";
Button btn = new Button();
btn.Content = Title;
btn.HorizontalAlignment = HorizontalAlignment.Center;
btn.VerticalAlignment = VerticalAlignment.Center;
btn.Click += ButtonOnClick;
Content = btn;
}
void ButtonOnClick(object sender, RoutedEventArgs args)
{
FontDialog dlg = new FontDialog();
dlg.Owner = this;
//윈도우의 폰트 대화상자 프로퍼티를 설정
dlg.Typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
dlg.FontSize = FontSize;
if (dlg.ShowDialog().GetValueOrDefault())
{
//폰트 대화상자에서 윈도우 프로퍼티를 설정
FontFamily = dlg.Typeface.FontFamily;
FontStyle = dlg.Typeface.Style;
FontWeight = dlg.Typeface.Weight;
FontStretch = dlg.Typeface.Stretch;
FontSize = dlg.FaceSize;
}
}
}
}
[ FontDialog.cs 파일]
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace ChooseFont
{
public class FontDialog : Window
{
TextBoxWithLister boxFamily, boxStyle, boxWeight, boxStretch, boxSize;
Label lblDisplay;
bool isUpdateSuppressed = true;
//Public 프로퍼티
public Typeface Typeface
{
set
{
if (boxFamily.Contains(value.FontFamily))
boxFamily.SelectedItem = value.FontFamily;
else
boxFamily.SelectedIndex = 0;
if (boxStyle.Contains(value.Style))
boxStyle.SelectedItem = value.Style;
else
boxStyle.SelectedIndex = 0;
if (boxWeight.Contains(value.Weight))
boxWeight.SelectedItem = value.Weight;
else
boxWeight.SelectedIndex = 0;
if (boxStretch.Contains(value.Stretch))
boxStretch.SelectedItem = value.Stretch;
else
boxStretch.SelectedIndex = 0;
}
get
{
return new Typeface((FontFamily)boxFamily.SelectedItem, (FontStyle)boxStyle.SelectedItem,
(FontWeight)boxWeight.SelectedItem, (FontStretch)boxStretch.SelectedItem);
}
}
public double FaceSize
{
set
{
double size = 0.75 * value;
boxSize.Text = size.ToString();
if (!boxSize.Contains(size)) boxSize.Insert(0, size);
boxSize.SelectedItem = size;
}
get
{
double size;
if (!Double.TryParse(boxSize.Text, out size)) size = 8.25;
return size / 0.75;
}
}
//생성자
public FontDialog()
{
Title = "Font";
ShowInTaskbar = false;
WindowStyle = WindowStyle.ToolWindow;
WindowStartupLocation = WindowStartupLocation.CenterOwner;
SizeToContent = SizeToContent.WidthAndHeight;
ResizeMode = ResizeMode.NoResize;
//윈도우 Content를 위해 3개 행을 가진 Grid를 생성
Grid gridMain = new Grid();
Content = gridMain;
//TextBoxWithLister 컨트롤을 위한 행
RowDefinition rowDef = new RowDefinition();
rowDef.Height = new GridLength(200, GridUnitType.Pixel);
gridMain.RowDefinitions.Add(rowDef);
//샘플 텍스트를 위한 행
rowDef = new RowDefinition();
rowDef.Height = new GridLength(150, GridUnitType.Pixel);
gridMain.RowDefinitions.Add(rowDef);
//버튼을 위한 행
rowDef = new RowDefinition();
rowDef.Height = GridLength.Auto;
gridMain.RowDefinitions.Add(rowDef);
//메인 Grid를 위한 행
ColumnDefinition colDef = new ColumnDefinition();
colDef.Width = new GridLength(650, GridUnitType.Pixel);
gridMain.ColumnDefinitions.Add(colDef);
//TextBoxWithLister 컨트롤을 위해 2개 행과 5개 열을 가진 Grid를 생성
Grid gridBoxes = new Grid();
gridMain.Children.Add(gridBoxes);
//라벨을 위한 행
rowDef = new RowDefinition();
rowDef.Height = GridLength.Auto;
gridBoxes.RowDefinitions.Add(rowDef);
//EditBoxWithLister 컨트롤을 위한 행
rowDef = new RowDefinition();
rowDef.Height = new GridLength(100, GridUnitType.Star);
gridBoxes.RowDefinitions.Add(rowDef);
//폰트 패밀리를 위한 첫 번째 열
colDef = new ColumnDefinition();
colDef.Width = new GridLength(175, GridUnitType.Star);
gridBoxes.ColumnDefinitions.Add(colDef);
//폰트 스타일을 위한 두 번째 열
colDef = new ColumnDefinition();
colDef.Width = new GridLength(100, GridUnitType.Star);
gridBoxes.ColumnDefinitions.Add(colDef);
//폰트 웨이트를 위한 세 번째 열
colDef = new ColumnDefinition();
colDef.Width = new GridLength(175, GridUnitType.Star);
gridBoxes.ColumnDefinitions.Add(colDef);
//폰트 스트레치를 위한 네 번째 열
colDef = new ColumnDefinition();
colDef.Width = new GridLength(100, GridUnitType.Star);
gridBoxes.ColumnDefinitions.Add(colDef);
//크기를 위한 다섯 번째 열
colDef = new ColumnDefinition();
colDef.Width = new GridLength(75, GridUnitType.Star);
gridBoxes.ColumnDefinitions.Add(colDef);
//TextBoxWithLister 컨트롤과 폰트 패밀리 레이블 생성
Label lbl = new Label();
lbl.Content = "Font Family";
lbl.Margin = new Thickness(12, 12, 12, 0);
gridBoxes.Children.Add(lbl);
Grid.SetRow(lbl, 0);
Grid.SetColumn(lbl, 0);
boxFamily = new TextBoxWithLister();
boxFamily.IsReadOnly = true;
boxFamily.Margin = new Thickness(12, 0, 12, 12);
gridBoxes.Children.Add(boxFamily);
Grid.SetRow(boxFamily, 1);
Grid.SetColumn(boxFamily, 0);
//TextBoxWithLister 컨트롤과 폰트 스타일 레이블 생성
lbl = new Label();
lbl.Content = "Style";
lbl.Margin = new Thickness(12, 12, 12, 0);
gridBoxes.Children.Add(lbl);
Grid.SetRow(lbl, 0);
Grid.SetColumn(lbl, 1);
boxStyle = new TextBoxWithLister();
boxStyle.IsReadOnly = true;
boxStyle.Margin = new Thickness(12, 0, 12, 12);
gridBoxes.Children.Add(boxStyle);
Grid.SetRow(boxStyle, 1);
Grid.SetColumn(boxStyle, 1);
//TextBoxWithLister 컨트롤과 폰트 웨이트 레이블 생성
lbl = new Label();
lbl.Content = "Weight";
lbl.Margin = new Thickness(12, 12, 12, 0);
gridBoxes.Children.Add(lbl);
Grid.SetRow(lbl, 0);
Grid.SetColumn(lbl, 2);
boxWeight = new TextBoxWithLister();
boxWeight.IsReadOnly = true;
boxWeight.Margin = new Thickness(12, 0, 12, 12);
gridBoxes.Children.Add(boxWeight);
Grid.SetRow(boxWeight, 1);
Grid.SetColumn(boxWeight, 2);
//TextBoxWithLister 컨트롤과 폰트 스트레치 레이블 생성
lbl = new Label();
lbl.Content = "Stretch";
lbl.Margin = new Thickness(12, 12, 12, 0);
gridBoxes.Children.Add(lbl);
Grid.SetRow(lbl, 0);
Grid.SetColumn(lbl, 3);
boxStretch = new TextBoxWithLister();
boxStretch.IsReadOnly = true;
boxStretch.Margin = new Thickness(12, 0, 12, 12);
gridBoxes.Children.Add(boxStretch);
Grid.SetRow(boxStretch, 1);
Grid.SetColumn(boxStretch, 3);
//TextBoxWithLister 컨트롤과 크기 레이블 생성
lbl = new Label();
lbl.Content = "Size";
lbl.Margin = new Thickness(12, 12, 12, 0);
gridBoxes.Children.Add(lbl);
Grid.SetRow(lbl, 0);
Grid.SetColumn(lbl, 4);
boxSize = new TextBoxWithLister();
boxSize.Margin = new Thickness(12, 0, 12, 12);
gridBoxes.Children.Add(boxSize);
Grid.SetRow(boxSize, 1);
Grid.SetColumn(boxSize, 4);
//샘플 텍스트를 보여주기 위한 레이블 생성
lblDisplay = new Label();
lblDisplay.Content = "AaBbCc XxYyZz 012345";
lblDisplay.HorizontalContentAlignment = HorizontalAlignment.Center;
lblDisplay.VerticalContentAlignment = VerticalAlignment.Center;
gridMain.Children.Add(lblDisplay);
Grid.SetRow(lblDisplay, 1);
//버튼을 위해 5개의 열을 가진 Grid를 생성
Grid gridButtons = new Grid();
gridMain.Children.Add(gridButtons);
Grid.SetRow(gridButtons, 2);
for (int i = 0; i < 5; i++)
{
gridButtons.ColumnDefinitions.Add(new ColumnDefinition());
}
//OK 버튼
Button btn = new Button();
btn.Content = "OK";
btn.IsDefault = true;
btn.HorizontalAlignment = HorizontalAlignment.Center;
btn.MinWidth = 60;
btn.Margin = new Thickness(12);
btn.Click += OkOnClick;
gridButtons.Children.Add(btn);
Grid.SetColumn(btn, 1);
//Cancel 버튼
btn = new Button();
btn.Content = "Cancel";
btn.IsCancel = true;
btn.HorizontalAlignment = HorizontalAlignment.Center;
btn.MinWidth = 60;
btn.Margin = new Thickness(12);
gridButtons.Children.Add(btn);
Grid.SetColumn(btn, 3);
//시스템 폰트 패밀리로 폰트 패밀리 박스를 초기화
foreach (FontFamily fam in Fonts.SystemFontFamilies)
{
boxFamily.Add(fam);
}
//폰트 크기 박스를 초기화
double[] ptSizes = new double[] { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 };
foreach (double ptSize in ptSizes)
{
boxSize.Add(ptSize);
}
//이벤트 핸들러를 설정
boxFamily.SelectionChanged += FamilyOnSelectionChanged;
boxStyle.SelectionChanged += StyleOnSelectionChanged;
boxWeight.SelectionChanged += StyleOnSelectionChanged;
boxStretch.SelectionChanged += StyleOnSelectionChanged;
boxSize.TextChanged += SizeOnTextChanged;
//윈도우 프로퍼티를 기반으로 선택 값을 설정
//(이 부분은 프로퍼티가 설정되면 오버라이딩됨)
Typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
FaceSize = FontSize;
//키보드 포커스를 설정
boxFamily.Focus();
//샘플 텍스트를 수정할 수 있게 함
isUpdateSuppressed = false;
UpdateSample();
}
//폰트 패밀리 박스에 대한 SelectionChanged 이벤트 핸들러
void FamilyOnSelectionChanged(object sender, EventArgs args)
{
//선택한 패밀리를 구함
FontFamily fontFamily = (FontFamily)boxFamily.SelectedItem;
//이전 스타일, 웨이트, 스트레치를 저장
//이 값은 이 메소드가 처음 불릴 때는 null
FontStyle? fntStyPrevious = (FontStyle?) boxStyle.SelectedItem;
FontWeight? fntWtPrevious = (FontWeight?) boxWeight.SelectedItem;
FontStretch? fntStrPrevious = (FontStretch?) boxStretch.SelectedItem;
//샘플이 보이지 않게 함
isUpdateSuppressed = true;
//스타일, 웨이트, 스트레치 박스를 지움
boxStyle.Clear();
boxWeight.Clear();
boxStretch.Clear();
//선택된 폰트 패밀리의 typefaces에 대해서 루프를 수행
foreach (FamilyTypeface ftf in fontFamily.FamilyTypefaces)
{
//boxStyle에 스타일을 추가(Normal이 가장 상위에 위치)
if (!boxStyle.Contains(ftf.Style))
{
if (ftf.Style == FontStyles.Normal)
boxStyle.Insert(0, ftf.Style);
else
boxStyle.Add(ftf.Style);
}
//boxWeight에 웨이트를 추가(Normal이 가장 상위에 위치)
if (!boxWeight.Contains(ftf.Weight))
{
if (ftf.Weight == FontWeights.Normal)
boxWeight.Insert(0, ftf.Weight);
else
boxWeight.Add(ftf.Weight);
}
//boxStretch에 스트레치를 추가(Normal이 가장 상위에 위치)
if (!boxStretch.Contains(ftf.Stretch))
{
if (ftf.Stretch == FontStretches.Normal)
boxStretch.Insert(0, ftf.Stretch);
else
boxStretch.Add(ftf.Stretch);
}
}
//boxStyle에 선택 항목을 설정
if (boxStyle.Contains(fntStyPrevious))
boxStyle.SelectedItem = fntStyPrevious;
else
boxStyle.SelectedIndex = 0;
//boxWeight에 선택 항목을 설정
if (boxWeight.Contains(fntWtPrevious))
boxWeight.SelectedItem = fntWtPrevious;
else
boxWeight.SelectedIndex = 0;
//boxStretch에 선택 항목을 설정
if (boxStretch.Contains(fntStrPrevious))
boxStretch.SelectedItem = fntStrPrevious;
else
boxStretch.SelectedIndex = 0;
//샘플 수정이 가능하게 하고 샘플을 갱신
isUpdateSuppressed = false;
UpdateSample();
}
//스타일, 웨이트, 스트레치 박스에 대한 SelectionChanged 이벤트 핸들러
void StyleOnSelectionChanged(object sender, EventArgs args)
{
UpdateSample();
}
//크기 박스에 대한 TextChanged 이벤트 핸들러
void SizeOnTextChanged(object sender, TextChangedEventArgs args)
{
UpdateSample();
}
//샘플 텍스트 갱신
void UpdateSample()
{
if (isUpdateSuppressed) return;
lblDisplay.FontFamily = (FontFamily)boxFamily.SelectedItem;
lblDisplay.FontStyle = (FontStyle)boxStyle.SelectedItem;
lblDisplay.FontWeight = (FontWeight)boxWeight.SelectedItem;
lblDisplay.FontStretch = (FontStretch)boxStretch.SelectedItem;
double size;
if (!Double.TryParse(boxSize.Text, out size))
size = 8.25;
lblDisplay.FontSize = size / 0.75;
}
//OK 버튼을 누르면 대화상자를 종료
void OkOnClick(object sender, RoutedEventArgs args)
{
DialogResult = true;
}
}
}
[TextBoxWithLister.cs 파일]
using System;
using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace ChooseFont
{
public class TextBoxWithLister : ContentControl
{
TextBox txtBox;
Lister lister;
bool isReadOnly;
//Public 이벤트
public event EventHandler SelectionChanged;
public event TextChangedEventHandler TextChanged;
//생성자
public TextBoxWithLister()
{
//윈도우 Content를 위해 DockPanel 생성
DockPanel dock = new DockPanel();
Content = dock;
//상단에 위치할 텍스트 박스
txtBox = new TextBox();
txtBox.TextChanged += TextBoxOnTextChanged;
dock.Children.Add(txtBox);
DockPanel.SetDock(txtBox, Dock.Top);
//DockPanel의 나머지에 Lister를 추가
lister = new Lister();
lister.SelectionChanged += ListerOnSelectionChanged;
dock.Children.Add(lister);
}
//텍스트 박스 항목과 관련된 Public 프로퍼티
public string Text
{
get { return txtBox.Text; }
set { txtBox.Text = value; }
}
public bool IsReadOnly
{
get { return isReadOnly; }
set { isReadOnly = value; }
}
//Lister 요소의 다른 public 프로퍼티 인터페이스
public object SelectedItem
{
set
{
lister.SelectedItem = value;
if (lister.SelectedItem != null)
txtBox.Text = lister.SelectedItem.ToString();
else
txtBox.Text = "";
}
get
{
return lister.SelectedItem;
}
}
public int SelectedIndex
{
set
{
lister.SelectedIndex = value;
if (lister.SelectedIndex == -1)
txtBox.Text = "";
else
txtBox.Text = lister.SelectedItem.ToString();
}
get
{
return lister.SelectedIndex;
}
}
public void Add(object obj)
{
lister.Add(obj);
}
public void Insert(int index, object obj)
{
lister.Insert(index, obj);
}
public void Clear()
{
lister.Clear();
}
public bool Contains(object obj)
{
return lister.Contains(obj);
}
//마우스를 클릭하면 키보드 포커스를 설정
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
Focus();
}
//키보드가 포커스를 갖게 되면 텍스트 박스에 포커스를 설정
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);
if (e.NewFocus == this)
{
txtBox.Focus();
if (SelectedIndex == -1 && lister.Count > 0)
SelectedIndex = 0;
}
}
//첫 문자를 입력하면 이 값을 GoToLetter 메소드로 넘김
protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
base.OnPreviewTextInput(e);
if (IsReadOnly)
{
lister.GoToLetter(e.Text[0]);
e.Handled = true;
}
}
//선택 항목을 변경하기 위해 커서 이동키를 처리
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
if (SelectedIndex == -1) return;
switch(e.Key)
{
case Key.Home:
if (lister.Count > 0) SelectedIndex = 0;
break;
case Key.End:
if (lister.Count > 0) SelectedIndex = lister.Count - 1;
break;
case Key.Up:
if (SelectedIndex > 0) SelectedIndex--;
break;
case Key.Down:
if (SelectedIndex < lister.Count - 1) SelectedIndex++;
break;
case Key.PageUp:
lister.PageUp();
break;
case Key.PageDown:
lister.PageDown();
break;
default:
return;
}
e.Handled = true;
}
//이벤트 핸들러와 트리거
void ListerOnSelectionChanged(object sender, EventArgs args)
{
if (SelectedIndex == -1)
txtBox.Text = "";
else
txtBox.Text = lister.SelectedItem.ToString();
OnSelectionChanged(args);
}
void TextBoxOnTextChanged(object sender, TextChangedEventArgs args)
{
if (TextChanged != null) TextChanged(this, args);
}
protected virtual void OnSelectionChanged(EventArgs args)
{
if (SelectionChanged != null) SelectionChanged(this, args);
}
}
}
[Lister.cs 파일]
using System;
using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace ChooseFont
{
public class Lister : ContentControl
{
ScrollViewer scroll;
StackPanel stack;
ArrayList list = new ArrayList();
int indexSelected = -1;
//Public 이벤트
public event EventHandler SelectionChanged;
//생성자
public Lister()
{
Focusable = false;
//윈도우의 Content를 ContentControl의 Border로 설정
Border border = new Border();
border.BorderThickness = new Thickness(1);
border.BorderBrush = SystemColors.ActiveBorderBrush;
border.Background = SystemColors.WindowBrush;
Content = border;
//border의 자식으로 ScrollViewer 생성
scroll = new ScrollViewer();
scroll.Focusable = false;
scroll.Padding = new Thickness(2, 0, 0, 0);
border.Child = scroll;
//ScrollViewer의 Content로 스택 패널을 생성
stack = new StackPanel();
scroll.Content = stack;
//마우스 왼쪽 버튼에 대한 핸들러를 연결
AddHandler(TextBlock.MouseLeftButtonDownEvent, new MouseButtonEventHandler(TextBlockOnMouseLeftButtonDown));
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
//Lister가 처음 보여질 때 뷰에 선택된 항목을 스크롤
ScrollIntoView();
}
//Lister에 항목을 추가하고, 삽입하는 Public 메소드
public void Add(object obj)
{
list.Add(obj);
TextBlock txtBlk = new TextBlock();
txtBlk.Text = obj.ToString();
stack.Children.Add(txtBlk);
}
public void Insert(int index, object obj)
{
list.Insert(index, obj);
TextBlock txtBlk = new TextBlock();
txtBlk.Text = obj.ToString();
stack.Children.Insert(index, txtBlk);
}
public void Clear()
{
SelectedIndex = -1;
stack.Children.Clear();
list.Clear();
}
public bool Contains(object obj)
{
return list.Contains(obj);
}
public int Count
{
get { return list.Count; }
}
//입력한 문자에 따라 항목이 선택되게 하기 위해 호출되는 메소드
public void GoToLetter(char ch)
{
int offset = SelectedIndex + 1;
for (int i = 0; i < Count; i++)
{
int index = (i + offset) % Count;
if (Char.ToUpper(ch) == Char.ToUpper(list[index].ToString()[0]))
{
SelectedIndex = index;
break;
}
}
}
//선택바를 출력하기 위한 SelectedIndex 프로퍼티
public int SelectedIndex
{
set
{
if (value < -1 || value >= Count)
throw new ArgumentOutOfRangeException("SelectedIndex");
if (value == indexSelected) return;
if (indexSelected != -1)
{
TextBlock txtBlk = stack.Children[indexSelected] as TextBlock;
txtBlk.Background = SystemColors.WindowBrush;
txtBlk.Foreground = SystemColors.WindowTextBrush;
}
indexSelected = value;
if (indexSelected > -1)
{
TextBlock txtBlk = stack.Children[indexSelected] as TextBlock;
txtBlk.Background = SystemColors.HighlightBrush;
txtBlk.Foreground = SystemColors.HighlightTextBrush;
}
ScrollIntoView();
//SelectionChanged 이벤트 트리거
OnSelectionChanged(EventArgs.Empty);
}
get
{
return indexSelected;
}
}
//SelectionItem 프로퍼티는 SelectedIndex를 이용
public object SelectedItem
{
set
{
SelectedIndex = list.IndexOf(value);
}
get
{
if (SelectedIndex > -1) return list[SelectedIndex];
return null;
}
}
//리스트에서 페이지 업, 페이지 다운하는 Public 메소드
public void PageUp()
{
if (SelectedIndex == -1 || Count == 0) return;
int index = SelectedIndex - (int)(Count * scroll.ViewportHeight / scroll.ExtentHeight);
if (index < 0) index = 0;
SelectedIndex = index;
}
public void PageDown()
{
if (SelectedIndex == -1 || Count == 0) return;
int index = SelectedIndex + (int)(Count * scroll.ViewportHeight / scroll.ExtentHeight);
if (index > Count - 1) index = Count - 1;
SelectedIndex = index;
}
//뷰에서 선택 항목을 스크롤하는 Private 메소드
void ScrollIntoView()
{
if (Count == 0 || SelectedIndex == -1 || scroll.ViewportHeight > scroll.ExtentHeight) return;
double heightPerItem = scroll.ExtentHeight / Count;
double offsetItemTop = SelectedIndex * heightPerItem;
double offsetItemBot = (SelectedIndex + 1) * heightPerItem;
if (offsetItemTop < scroll.VerticalOffset) scroll.ScrollToVerticalOffset(offsetItemTop);
else if (offsetItemBot > scroll.VerticalOffset + scroll.ViewportHeight)
{
scroll.ScrollToVerticalOffset(scroll.VerticalOffset + offsetItemBot - scroll.VerticalOffset - scroll.ViewportHeight);
}
}
//이벤트 핸들러와 트리거
void TextBlockOnMouseLeftButtonDown(object sender, MouseButtonEventArgs args)
{
if (args.Source is TextBlock)
SelectedIndex = stack.Children.IndexOf(args.Source as TextBlock);
}
protected virtual void OnSelectionChanged(EventArgs args)
{
if (SelectionChanged != null)
SelectionChanged(this, args);
}
}
}