■ 네비게이션바 사용하기
------------------------------------------------------------------------------------------------------------------------
▶ DatePicker.xaml
<UserControl x:Class="TestProject.DatePicker" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:g="clr-namespace:System.Globalization;assembly=mscorlib"> <UserControl.Resources> <Style TargetType="{x:Type RepeatButton}"> <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource self}, Path=ActualHeight}" /> <Setter Property="Focusable" Value="False" /> <Style.Triggers> <DataTrigger Binding="{Binding ElementName=notApplicableCheckBox, Path=IsChecked}" Value="True"> <Setter Property="IsEnabled" Value="False" /> </DataTrigger> </Style.Triggers> </Style> <Style TargetType="{x:Type StatusBarItem}"> <Setter Property="Margin" Value="1" /> <Setter Property="HorizontalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" /> </Style> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderBrush" Value="Transparent" /> <Setter Property="Margin" Value="1" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="True" /> <Condition Property="Selector.IsSelectionActive" Value="False" /> </MultiTrigger.Conditions> <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" /> </MultiTrigger> <DataTrigger Binding="{Binding ElementName=notApplicableCheckBox, Path=IsChecked}" Value="True"> <Setter Property="IsEnabled" Value="False" /> </DataTrigger> </Style.Triggers> </Style> </UserControl.Resources> <Border BorderThickness="1" BorderBrush="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid Background="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}" TextBlock.Foreground="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <RepeatButton Grid.Column="0" Content="<" FontWeight="Bold" Click="backRepeatButton_Click" /> <TextBlock Name="yearMonthTextBlock" Grid.Column="1" Margin="3" HorizontalAlignment="Center" VerticalAlignment="Center" /> <RepeatButton Grid.Column="2" FontWeight="Bold" Content=">" Click="forwardRepeatButton_Click" /> </Grid> <StatusBar Grid.Row="1" ItemsSource="{Binding Source={x:Static g:DateTimeFormatInfo.CurrentInfo}, Path=AbbreviatedDayNames}"> <StatusBar.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Rows="1" /> </ItemsPanelTemplate> </StatusBar.ItemsPanel> </StatusBar> <Border Grid.Row="2" BorderThickness="0 1 0 1" BorderBrush="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"> <ListBox Name="monthListBox" SelectionChanged="monthListBox_SelectionChanged"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Name="monthUniformGrid" Rows="6" Columns="7" IsItemsHost="True" Background="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBoxItem>항목 없음</ListBoxItem> </ListBox> </Border> <CheckBox Name="notApplicableCheckBox" Grid.Row="3" Margin="3" HorizontalAlignment="Center" VerticalAlignment="Center" Checked="notApplicableCheckBox_Checked" Unchecked="notApplicableCheckBox_Unchecked"> 미적용 </CheckBox> </Grid> </Border> </UserControl>
|
▶ DatePicker.xaml.cs
using System; using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Media;
namespace TestProject { /// <summary> /// 데이트 피커 /// </summary> public partial class DatePicker : UserControl { //////////////////////////////////////////////////////////////////////////////////////////////////// Declaration ////////////////////////////////////////////////////////////////////////////////////////// Public
#region Event
/// <summary> /// 일자 변경시 /// </summary> public event RoutedPropertyChangedEventHandler<DateTime?> DateChanged { add { AddHandler(DateChangedEvent, value); } remove { RemoveHandler(DateChangedEvent, value); } }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary> /// 일자 속성 /// </summary> public static readonly DependencyProperty DateProperty = DependencyProperty.Register ( "Date", typeof(DateTime?), typeof(DatePicker), new PropertyMetadata ( new DateTime(), DatePropertyChangedCallback ) );
/// <summary> /// 일자 변경 이벤트 /// </summary> public static readonly RoutedEvent DateChangedEvent = EventManager.RegisterRoutedEvent ( "DateChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<DateTime?>), typeof(DatePicker) );
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary> /// 월 유니폼 그리드 /// </summary> private UniformGrid monthUniformGrid;
/// <summary> /// 저장일 /// </summary> private DateTime saveDate = DateTime.Now.Date;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 일자 - Date
/// <summary> /// 일자 /// </summary> public DateTime? Date { set { SetValue(DateProperty, value); } get { return (DateTime?)GetValue(DateProperty); } }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - DatePicker()
/// <summary> /// 생성자 /// </summary> public DatePicker() { InitializeComponent();
Date = this.saveDate;
Loaded += UserControl_Loaded; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 프리뷰 키 하강시 처리하기 - OnPreviewKeyDown(e)
/// <summary> /// 프리뷰 키 하강시 처리하기 /// </summary> /// <param name="e">이벤트 인자</param> protected override void OnPreviewKeyDown(KeyEventArgs e) { base.OnKeyDown(e);
if(e.Key == Key.PageDown) { FlipPage(true);
e.Handled = true; } else if(e.Key == Key.PageUp) { FlipPage(false);
e.Handled = false; } }
#endregion #region 일자 변경시 처리하기 - OnDateChanged(beforeDate, afterDate)
/// <summary> /// 일자 변경시 처리하기 /// </summary> /// <param name="beforeDate">변경전 일시</param> /// <param name="afterDate">변경후 일시</param> protected virtual void OnDateChanged(DateTime? beforeDate, DateTime? afterDate) { this.notApplicableCheckBox.IsChecked = afterDate == null;
if(afterDate != null) { DateTime newDate = (DateTime)afterDate;
this.yearMonthTextBlock.Text = newDate.ToString(DateTimeFormatInfo.CurrentInfo.YearMonthPattern);
if(this.monthUniformGrid != null) { this.monthUniformGrid.FirstColumn = (int)(new DateTime(newDate.Year, newDate.Month, 1).DayOfWeek); }
int dayCountInMonth = DateTime.DaysInMonth(newDate.Year, newDate.Month);
if(dayCountInMonth != this.monthListBox.Items.Count) { this.monthListBox.BeginInit();
this.monthListBox.Items.Clear();
for(int i = 0; i < dayCountInMonth; i++) { this.monthListBox.Items.Add((i + 1).ToString()); }
this.monthListBox.EndInit(); }
this.monthListBox.SelectedIndex = newDate.Day - 1; }
RoutedPropertyChangedEventArgs<DateTime?> routedPropertyChangedEventArgs = new RoutedPropertyChangedEventArgs<DateTime?>(beforeDate, afterDate, DatePicker.DateChangedEvent);
routedPropertyChangedEventArgs.Source = this;
RaiseEvent(routedPropertyChangedEventArgs); }
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event
#region 사용자 컨트롤 로드시 처리하기 - UserControl_Loaded(sender, e)
/// <summary> /// 사용자 컨트롤 로드시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void UserControl_Loaded(object sender, RoutedEventArgs e) { this.monthUniformGrid = FindUniformGrid(monthListBox);
if(Date != null) { DateTime date = (DateTime)Date;
this.monthUniformGrid.FirstColumn = (int)(new DateTime(date.Year, date.Month, 1).DayOfWeek); } }
#endregion #region 뒤로 리피트 버튼 클릭시 처리하기 - backRepeatButton_Click(sender, e)
/// <summary> /// 뒤로 리피트 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void backRepeatButton_Click(object sender, RoutedEventArgs e) { FlipPage(true); }
#endregion #region 앞으로 리피트 버튼 클릭시 처리하기 - forwardRepeatButton_Click(sender, e)
/// <summary> /// 앞으로 리피트 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void forwardRepeatButton_Click(object sender, RoutedEventArgs e) { FlipPage(false); }
#endregion #region 월 리스트 박스 선택 변경시 처리하기 - monthListBox_SelectionChanged(sender, e)
/// <summary> /// 월 리스트 박스 선택 변경시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void monthListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if(Date == null) { return; }
DateTime date = (DateTime)Date;
if(this.monthListBox.SelectedIndex != -1) { Date = new DateTime ( date.Year, date.Month, Int32.Parse(this.monthListBox.SelectedItem as string) ); } }
#endregion #region 미적용 체크 박스 체크시 처리하기 - notApplicableCheckBox_Checked(sender, e)
/// <summary> /// 미적용 체크 박스 체크시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void notApplicableCheckBox_Checked(object sender, RoutedEventArgs e) { if(Date != null) { this.saveDate = (DateTime)Date;
Date = null; } }
#endregion #region 미적용 체크 박스 체크 해제시 처리하기 - notApplicableCheckBox_Unchecked(sender, e)
/// <summary> /// 미적용 체크 박스 체크 해제시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void notApplicableCheckBox_Unchecked(object sender, RoutedEventArgs e) { Date = this.saveDate; }
#endregion #region 일자 속성 변경시 콜백 - DatePropertyChangedCallback(dependencyObject, e)
/// <summary> /// 일자 속성 변경시 콜백 /// </summary> /// <param name="dependencyObject">의존 객체</param> /// <param name="e">의존 속성 변경 이벤트 인자</param> private static void DatePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) { (dependencyObject as DatePicker).OnDateChanged ( (DateTime?)e.OldValue, (DateTime?)e.NewValue ); }
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 유니폼 그리드 찾기 - FindUniformGrid(dependencyObject)
/// <summary> /// 유니폼 그리드 찾기 /// </summary> /// <param name="dependencyObject">의존 객체</param> /// <returns>유니폼 그리드</returns> private UniformGrid FindUniformGrid(DependencyObject dependencyObject) { if(dependencyObject is UniformGrid) { return dependencyObject as UniformGrid; }
for(int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++) { Visual visual = FindUniformGrid(VisualTreeHelper.GetChild(dependencyObject, i));
if(visual != null) { return visual as UniformGrid; } }
return null; }
#endregion #region 페이지 플립하기 - FlipPage(isBack)
/// <summary> /// 페이지 플립하기 /// </summary> /// <param name="isBack">뒤로 여부</param> private void FlipPage(bool isBack) { if(Date == null) { return; }
DateTime date = (DateTime)Date;
int pageCount = isBack ? -1 : 1;
if(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) { pageCount *= 12; }
if(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) { pageCount = Math.Max(-1200, Math.Min(1200, 120 * pageCount)); }
int year = date.Year + pageCount / 12; int month = date.Month + pageCount % 12;
while(month < 1) { month += 12; year -= 1; } while (month > 12) { month -= 12; year += 1; }
if(year < DateTime.MinValue.Year) { Date = DateTime.MinValue.Date; } else if(year > DateTime.MaxValue.Year) { Date = DateTime.MaxValue.Date; } else { Date = new DateTime(year, month, Math.Min(date.Day, DateTime.DaysInMonth(year, month))); } }
#endregion } }
|
▶ NavigationBar.xaml
<ToolBar x:Class="TestProject.NavigationBar" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ToolBar.Resources> <Style x:Key="ButtonStyleKey" TargetType="Button"> <Setter Property="Margin" Value="2" /> </Style> <Style x:Key="ImageStyleKey" TargetType="Image"> <Setter Property="HorizontalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="Width" Value="16px" /> <Setter Property="Height" Value="16px" /> <Setter Property="RenderOptions.BitmapScalingMode" Value="NearestNeighbor" /> <Setter Property="Stretch" Value="UniformToFill" /> </Style> </ToolBar.Resources> <Button Name="moveFirstButton" Style="{StaticResource ButtonStyleKey}" ToolTip="첫 번째 항목으로" Click="moveFirstButton_Click"> <Image Style="{StaticResource ImageStyleKey}" Source="/Image/MoveFirst.png" /> </Button> <Button Name="movePreviousButton" Style="{StaticResource ButtonStyleKey}" ToolTip="이전 항목으로" Click="movePreviousButton_Click"> <Image Style="{StaticResource ImageStyleKey}" Source="/Image/MovePrevious.png" /> </Button> <Separator /> <TextBox Name="currentPositionTextBox" Width="50" TextAlignment="Right" ToolTip="현재 항목 위치" GotKeyboardFocus="currentPositionTextBox_GotFocus" LostKeyboardFocus="currentPositionTextBox_LostFocus" KeyDown="currentPositionTextBox_KeyDown" TextChanged="currentPositionTextBox_TextChanged" /> <TextBlock Text=" / " VerticalAlignment="Center" /> <TextBlock Name="totalCountTextBlock" VerticalAlignment="Center" ToolTip="전체 항목 수" Text="0" /> <Separator /> <Button Name="moveNextButton" Style="{StaticResource ButtonStyleKey}" ToolTip="다음 항목으로" Click="moveNextButton_Click"> <Image Style="{StaticResource ImageStyleKey}" Source="/Image/MoveNext.png" /> </Button> <Button Name="moveLastButton" Style="{StaticResource ButtonStyleKey}" ToolTip="마지막 항목으로" Click="moveLastButton_Click"> <Image Style="{StaticResource ImageStyleKey}" Source="/Image/MoveLast.png" /> </Button> <Separator /> <Button Name="addNewButton" Style="{StaticResource ButtonStyleKey}" ToolTip="신규 추가" Click="addNewButton_Click"> <Image Style="{StaticResource ImageStyleKey}" Source="/Image/AddNew.png" /> </Button> <Button Name="deleteButton" Style="{StaticResource ButtonStyleKey}" ToolTip="삭제" Click="deleteButton_Click"> <Image Style="{StaticResource ImageStyleKey}" Source="/Image/Delete.png" /> </Button> </ToolBar>
|
▶ NavigationBar.xaml.cs
using System; using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input;
namespace TestProject { /// <summary> /// 네비게이션 바 /// </summary> public partial class NavigationBar : ToolBar { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary> /// 리스트 /// </summary> private IList list;
/// <summary> /// 컬렉션 뷰 /// </summary> private ICollectionView collectionView;
/// <summary> /// 항목 타입 /// </summary> private Type itemType;
/// <summary> /// 오리지널 위치 /// </summary> private string originalPosition;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 항목 타입 - ItemType
/// <summary> /// 항목 타입 /// </summary> public Type ItemType { get { return this.itemType; } set { this.itemType = value; } }
#endregion #region 컬렉션 - Collection
/// <summary> /// 컬렉션 /// </summary> public IList Collection { set { this.list = value;
this.collectionView = CollectionViewSource.GetDefaultView(this.list);
this.collectionView.CurrentChanged += collectionView_CurrentChanged; this.collectionView.CollectionChanged += collectionView_CollectionChanged;
collectionView_CurrentChanged(null, null);
this.totalCountTextBlock.Text = this.list.Count.ToString(); } get { return this.list; } }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - NavigationBar()
/// <summary> /// 생성자 /// </summary> public NavigationBar() { InitializeComponent(); }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private
#region 컬렉션 뷰 컬렉션 변경시 처리하기 - collectionView_CollectionChanged(sender, e)
/// <summary> /// 컬렉션 뷰 컬렉션 변경시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void collectionView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { this.totalCountTextBlock.Text = this.list.Count.ToString(); }
#endregion #region 컬렉션 뷰 현재 변경시 처리하기 - collectionView_CurrentChanged(sender, e)
/// <summary> /// 컬렉션 뷰 현재 변경시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void collectionView_CurrentChanged(object sender, EventArgs e) { this.currentPositionTextBox.Text = (1 + this.collectionView.CurrentPosition).ToString();
this.movePreviousButton.IsEnabled = this.collectionView.CurrentPosition > 0; this.moveNextButton.IsEnabled = this.collectionView.CurrentPosition < this.list.Count - 1; this.deleteButton.IsEnabled = this.list.Count > 1; }
#endregion #region Move First 버튼 클릭시 처리하기 - moveFirstButton_Click(sender, e)
/// <summary> /// Move First 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void moveFirstButton_Click(object sender, RoutedEventArgs e) { this.collectionView.MoveCurrentToFirst(); }
#endregion #region Move Previous 버튼 클릭시 처리하기 - movePreviousButton_Click(sender, e)
/// <summary> /// Move Previous 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void movePreviousButton_Click(object sender, RoutedEventArgs e) { this.collectionView.MoveCurrentToPrevious(); }
#endregion #region Move Next 버튼 클릭시 처리하기 - moveNextButton_Click(sender, e)
/// <summary> /// Move Next 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void moveNextButton_Click(object sender, RoutedEventArgs e) { this.collectionView.MoveCurrentToNext(); }
#endregion #region Move Last 버튼 클릭시 처리하기 - moveLastButton_Click(sender, e)
/// <summary> /// Move Next 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void moveLastButton_Click(object sender, RoutedEventArgs e) { this.collectionView.MoveCurrentToLast(); }
#endregion #region Add New 버튼 클릭시 처리하기 - addNewButton_Click(sender, e)
/// <summary> /// Add New 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void addNewButton_Click(object sender, RoutedEventArgs e) { ConstructorInfo constructorInfo = this.itemType.GetConstructor(Type.EmptyTypes);
this.list.Add(constructorInfo.Invoke(null));
this.collectionView.MoveCurrentToLast(); }
#endregion #region Delete 버튼 클릭시 처리하기 - deleteButton_Click(sender, e)
/// <summary> /// Delete 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void deleteButton_Click(object sender, RoutedEventArgs e) { this.list.RemoveAt(this.collectionView.CurrentPosition); }
#endregion #region 현재 위치 텍스트 박스 포커스 획득시 처리하기 - currentPositionTextBox_GotFocus(sender, e)
/// <summary> /// 현재 위치 텍스트 박스 포커스 획득시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void currentPositionTextBox_GotFocus(object sender, KeyboardFocusChangedEventArgs e) { originalPosition = this.currentPositionTextBox.Text; }
#endregion #region 현재 위치 텍스트 박스 포커스 상실시 처리하기 - currentPositionTextBox_LostFocus(sender, e)
/// <summary> /// 현재 위치 텍스트 박스 포커스 상실시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void currentPositionTextBox_LostFocus(object sender, KeyboardFocusChangedEventArgs e) { int currentPosition;
if(int.TryParse(this.currentPositionTextBox.Text, out currentPosition)) { if(currentPosition > 0 && currentPosition <= this.list.Count) { this.collectionView.MoveCurrentToPosition(currentPosition - 1); } else { this.currentPositionTextBox.Text = this.originalPosition; } } }
#endregion #region 현재 위치 텍스트 박스 키 DOWN 처리하기 - currentPositionTextBox_KeyDown(sender, e)
/// <summary> /// 현재 위치 텍스트 박스 키 DOWN 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void currentPositionTextBox_KeyDown(object sender, KeyEventArgs e) { if(e.Key == Key.Escape) { this.currentPositionTextBox.Text = originalPosition;
e.Handled = true; } else if(e.Key == Key.Enter) { e.Handled = true; } else { return; }
MoveFocus(new TraversalRequest(FocusNavigationDirection.Right)); }
#endregion #region 현재 위치 텍스트 박스 텍스트 변경시 처리하기 - currentPositionTextBox_TextChanged(sender, e)
/// <summary> /// 현재 위치 텍스트 박스 텍스트 변경시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void currentPositionTextBox_TextChanged(object sender, TextChangedEventArgs e) { TextBox textBox = sender as TextBox; int selectionStart = textBox.SelectionStart; int selectionLength = textBox.SelectionLength; string result = string.Empty;
foreach(char character in textBox.Text.ToCharArray()) { if(char.IsDigit(character) || char.IsControl(character)) { result += character; } }
textBox.Text = result;
textBox.SelectionStart = selectionStart <= textBox.Text.Length ? selectionStart : textBox.Text.Length; }
#endregion } }
|
▶ PersonPanel.xaml
<Grid x:Class="TestProject.PersonPanel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TestProject"> <Grid.Resources> <Style TargetType="{x:Type Label}"> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="Margin" Value="12" /> </Style> <Style TargetType="{x:Type TextBox}"> <Setter Property="Margin" Value="12" /> </Style> <Style TargetType="{x:Type local:DatePicker}"> <Setter Property="Margin" Value="12" /> </Style> </Grid.Resources> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Content="이름(_F) : " /> <TextBox Grid.Row="0" Grid.Column="1" Margin="12" Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <Label Grid.Row="1" Grid.Column="0" Content="중간 이름(_M) : " /> <TextBox Grid.Row="1" Grid.Column="1" Margin="12" Text="{Binding Path=MiddleName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <Label Grid.Row="2" Grid.Column="0" Content="성(_L) : " /> <TextBox Grid.Row="2" Grid.Column="1" Margin="12" Text="{Binding Path=LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <Label Grid.Row="3" Grid.Column="0" Content="생일(_B) : " /> <local:DatePicker Grid.Row="3" Grid.Column="1" Margin="12" HorizontalAlignment="Center" Date="{Binding Path=BirthDate, Mode=TwoWay}" /> <Label Grid.Row="4" Grid.Column="0" Content="사망일(_D) : " /> <local:DatePicker Grid.Row="4" Grid.Column="1" Margin="12" HorizontalAlignment="Center" Date="{Binding Path=DeathDate, Mode=TwoWay}" /> </Grid>
|
▶ PersonPanel.xaml.cs
using System.Windows.Controls;
namespace TestProject { /// <summary> /// 인명부 패널 /// </summary> public partial class PersonPanel : Grid { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - PersonPanel()
/// <summary> /// 생성자 /// </summary> public PersonPanel() { InitializeComponent(); }
#endregion } }
|
▶ MainWindow.xaml
<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" ResizeMode="CanMinimize" SizeToContent="WidthAndHeight" FontFamily="맑은 고딕" FontSize="12pt" Title="네비게이션바 사용하기"> <DockPanel> <Menu DockPanel.Dock="Top" FontSize="12pt"> <MenuItem Header="파일(_F)"> <MenuItem Header="추가(_N)" Command="New" /> <MenuItem Header="열기(_O)..." Command="Open" /> <MenuItem Header="저장(_S)..." Command="Save" /> </MenuItem> </Menu> <local:NavigationBar x:Name="navigationBar" DockPanel.Dock="Bottom" /> <local:PersonPanel x:Name="personPanel" /> </DockPanel> <Window.CommandBindings> <CommandBinding Command="New" Executed="New_Executed" /> <CommandBinding Command="Open" Executed="Open_Executed" /> <CommandBinding Command="Save" Executed="Save_Executed" /> </Window.CommandBindings> </Window>
|
▶ MainWindow.xaml.cs
using System.Windows.Input;
namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary> /// 사람 컬렉션 /// </summary> private PersonCollection personCollection;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent();
ApplicationCommands.New.Execute(null, this);
this.personPanel.Children[1].Focus(); }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event
#region New 실행시 처리하기 - New_Executed(sender, e)
/// <summary> /// New 실행시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void New_Executed(object sender, ExecutedRoutedEventArgs e) { this.personCollection = new PersonCollection();
this.personCollection.Add(new Person());
InitializeNewPeopleObject(); }
#endregion #region Open 실행시 처리하기 - Open_Executed(sender, e)
/// <summary> /// Open 실행시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void Open_Executed(object sender, ExecutedRoutedEventArgs e) { this.personCollection = PersonCollection.Load(this);
InitializeNewPeopleObject(); }
#endregion #region Save 실행시 처리하기 - Save_Executed(sender, e)
/// <summary> /// Save 실행시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void Save_Executed(object sender, ExecutedRoutedEventArgs e) { this.personCollection.Save(this); }
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 새 People 객체 초기화 하기 - InitializeNewPeopleObject()
/// <summary> /// 새 People 객체 초기화 하기 /// </summary> private void InitializeNewPeopleObject() { this.navigationBar.Collection = this.personCollection;
this.navigationBar.ItemType = typeof(Person);
this.personPanel.DataContext = this.personCollection; }
#endregion } }
|
------------------------------------------------------------------------------------------------------------------------
'C# > WPF' 카테고리의 다른 글
[C#/WPF] DiffuseMaterial 클래스 사용하기 (0) | 2019.06.30 |
---|---|
[C#/WPF] Model3DGroup 클래스 사용하기 (0) | 2019.06.30 |
[C#/WPF] MeshGeometry3D 클래스 : TriangleIndices 속성을 사용해 삼각형 만들기 (0) | 2019.06.30 |
[C#/WPF] DataGrid 클래스 : DataTable 바인딩 하기 (0) | 2019.06.30 |
[C#/WPF] Frame 클래스 사용하기 (0) | 2019.06.29 |
[C#/WPF] 네비게이션바 사용하기 (0) | 2019.06.29 |
[C#/WPF] 필기장 사용하기 (0) | 2019.06.29 |
[C#/WPF] ListBox 클래스 : ItemTemplate 속성 사용하기 (0) | 2019.06.29 |
[C#/WPF] ListView 클래스 : 항목 드래그시 스크롤하기 (0) | 2019.06.29 |
[C#/WPF] ListView 클래스 : 항목 드래그 & 드롭 사용하기 (0) | 2019.06.29 |
[C#/WPF] 시스템 메뉴 표시하기 (0) | 2019.06.29 |
댓글을 달아 주세요