728x90
반응형
728x170
▶ ColorCell.cs
using System;
using System.Windows;
using System.Windows.Media;
namespace TestProject
{
/// <summary>
/// 색상 셀
/// </summary>
public class ColorCell : FrameworkElement
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 선택 여부 속성
/// </summary>
public static readonly DependencyProperty IsSelectedProperty;
/// <summary>
/// 하이라이트 여부 속성
/// </summary>
public static readonly DependencyProperty IsHighlightedProperty;
#endregion
//////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 셀 크기
/// </summary>
private static readonly Size _cellSize = new Size(20, 20);
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 색상 드로잉 비주얼
/// </summary>
private DrawingVisual colorDrawingVisual;
/// <summary>
/// 브러시
/// </summary>
private Brush brush;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 선택 여부 - IsSelected
/// <summary>
/// 선택 여부
/// </summary>
public bool IsSelected
{
set
{
SetValue(IsSelectedProperty, value);
}
get
{
return (bool)GetValue(IsSelectedProperty);
}
}
#endregion
#region 하이라이트 여부 - IsHighlighted
/// <summary>
/// 하이라이트 여부
/// </summary>
public bool IsHighlighted
{
set
{
SetValue(IsHighlightedProperty, value);
}
get
{
return (bool)GetValue(IsHighlightedProperty);
}
}
#endregion
#region 브러시 - Brush
/// <summary>
/// 브러시
/// </summary>
public Brush Brush
{
get
{
return this.brush;
}
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 비주얼 자식 수 - VisualChildrenCount
/// <summary>
/// 비주얼 자식 수
/// </summary>
protected override int VisualChildrenCount
{
get
{
return 1;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Static
#region 생성자 - ColorCell()
/// <summary>
/// 생성자
/// </summary>
static ColorCell()
{
IsSelectedProperty = DependencyProperty.Register
(
"IsSelected",
typeof(bool),
typeof(ColorCell),
new FrameworkPropertyMetadata
(
false,
FrameworkPropertyMetadataOptions.AffectsRender
)
);
IsHighlightedProperty = DependencyProperty.Register
(
"IsHighlighted",
typeof(bool),
typeof(ColorCell),
new FrameworkPropertyMetadata
(
false,
FrameworkPropertyMetadataOptions.AffectsRender
)
);
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - ColorCell(color)
/// <summary>
/// 생성자
/// </summary>
/// <param name="color">색상</param>
public ColorCell(Color color)
{
this.colorDrawingVisual = new DrawingVisual();
DrawingContext drawingContext = this.colorDrawingVisual.RenderOpen();
Rect rect = new Rect(new Point(0, 0), _cellSize);
rect.Inflate(-4, -4);
Pen pen = new Pen(SystemColors.ControlTextBrush, 1);
this.brush = new SolidColorBrush(color);
drawingContext.DrawRectangle(this.brush, pen, rect);
drawingContext.Close();
AddVisualChild(this.colorDrawingVisual);
AddLogicalChild(this.colorDrawingVisual);
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Method
//////////////////////////////////////////////////////////////////////////////// Protected
#region 비주얼 자식 구하기 - GetVisualChild(index)
/// <summary>
/// 비주얼 자식 구하기
/// </summary>
/// <param name="index">인덱스</param>
/// <returns>비주얼 자식</returns>
protected override Visual GetVisualChild(int index)
{
if(index > 0)
{
throw new ArgumentOutOfRangeException("index");
}
return this.colorDrawingVisual;
}
#endregion
#region 측정하기 (오버라이딩) - MeasureOverride(availableSize)
/// <summary>
/// 측정하기 (오버라이딩)
/// </summary>
/// <param name="availableSize">이용 가능한 크기</param>
/// <returns>측정 크기</returns>
protected override Size MeasureOverride(Size availableSize)
{
return _cellSize;
}
#endregion
#region 렌더링 처리하기 - OnRender(drawingContext)
/// <summary>
/// 렌더링 처리하기
/// </summary>
/// <param name="drawingContext">DrawingContext</param>
protected override void OnRender(DrawingContext drawingContext)
{
Rect rect = new Rect(new Point(0, 0), RenderSize);
rect.Inflate(-1, -1);
Pen pen = new Pen(SystemColors.HighlightBrush, 1);
if(IsHighlighted)
{
drawingContext.DrawRectangle(SystemColors.ControlDarkBrush, pen, rect);
}
else if(IsSelected)
{
drawingContext.DrawRectangle(SystemColors.ControlLightBrush, pen, rect);
}
else
{
drawingContext.DrawRectangle(Brushes.Transparent, null, rect);
}
}
#endregion
}
}
728x90
▶ ColorGrid.cs
using System;
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 class ColorGrid : Control
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Event
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 선택 색상 변경시 - SelectedColorChanged
/// <summary>
/// 선택 색상 변경시
/// </summary>
public event EventHandler SelectedColorChanged;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 행 수
/// </summary>
private const int ROW_COUNT = 5;
/// <summary>
/// 컬럼 수
/// </summary>
private const int COLUMN_COUNT = 8;
/// <summary>
/// 색상 문자열 배열
/// </summary>
private string[,] colorStringArray = new string[ROW_COUNT, COLUMN_COUNT]
{
{ "Black" , "Brown" , "DarkGreen" , "MidnightBlue", "Navy" , "DarkBlue" , "Indigo" , "DimGray" },
{ "DarkRed" , "OrangeRed", "Olive" , "Green" , "Teal" , "Blue" , "SlateGray", "Gray" },
{ "Red" , "Orange" , "YellowGreen", "SeaGreen" , "Aqua" , "LightBlue" , "Violet" , "DarkGray" },
{ "Pink" , "Gold" , "Yellow" , "Lime" , "Turquoise", "SkyBlue" , "Plum" , "LightGray" },
{ "LightPink", "Tan" , "LightYellow", "LightGreen" , "LightCyan", "LightSkyBlue", "Lavender" , "White" }
};
/// <summary>
/// 색상 셀 배열
/// </summary>
private ColorCell[,] colorCellArray = new ColorCell[ROW_COUNT, COLUMN_COUNT];
/// <summary>
/// 선택 색상 셀
/// </summary>
private ColorCell selectedColorCell;
/// <summary>
/// 하이라이트 색상 셀
/// </summary>
private ColorCell highlightedColorCell;
/// <summary>
/// 테두리
/// </summary>
private Border border;
/// <summary>
/// 유니폼 그리드
/// </summary>
private UniformGrid uniformGrid;
/// <summary>
/// 선택 색상
/// </summary>
private Color selectedColor = Colors.Black;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 선택 색상 - SelectedColor
/// <summary>
/// 선택 색상
/// </summary>
public Color SelectedColor
{
get
{
return this.selectedColor;
}
}
#endregion
#region 비주얼 자식 수 - VisualChildrenCount
/// <summary>
/// 비주얼 자식 수
/// </summary>
protected override int VisualChildrenCount
{
get
{
return 1;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - ColorGrid()
/// <summary>
/// 생성자
/// </summary>
public ColorGrid()
{
this.border = new Border();
this.border.BorderBrush = SystemColors.ControlDarkDarkBrush;
this.border.BorderThickness = new Thickness(1);
AddVisualChild(this.border);
AddLogicalChild(this.border);
this.uniformGrid = new UniformGrid();
this.uniformGrid.Background = SystemColors.WindowBrush;
this.uniformGrid.Columns = COLUMN_COUNT;
this.border.Child = this.uniformGrid;
for(int y = 0; y < ROW_COUNT; y++)
{
for(int x = 0; x < COLUMN_COUNT; x++)
{
Color color = (Color)typeof(Colors).GetProperty(colorStringArray[y, x]).GetValue(null, null);
this.colorCellArray[y, x] = new ColorCell(color);
this.uniformGrid.Children.Add(this.colorCellArray[y, x]);
if(color == SelectedColor)
{
this.selectedColorCell = this.colorCellArray[y, x];
this.colorCellArray[y, x].IsSelected = true;
}
ToolTip toolTip = new ToolTip();
toolTip.Content = colorStringArray[y, x];
this.colorCellArray[y, x].ToolTip = toolTip;
}
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 비주얼 자식 구하기 - GetVisualChild(index)
/// <summary>
/// 비주얼 자식 구하기
/// </summary>
/// <param name="index">인덱스</param>
/// <returns></returns>
protected override Visual GetVisualChild(int index)
{
if(index > 0)
{
throw new ArgumentOutOfRangeException("index");
}
return this.border;
}
#endregion
#region 측정하기 (오버라이딩) - MeasureOverride(availableSize)
/// <summary>
/// 측정하기 (오버라이딩)
/// </summary>
/// <param name="availableSize">이용 가능한 크기</param>
/// <returns>측정 크기</returns>
protected override Size MeasureOverride(Size availableSize)
{
this.border.Measure(availableSize);
return this.border.DesiredSize;
}
#endregion
#region 배열하기 (오버라이딩) - ArrangeOverride(finalSize)
/// <summary>
/// 배열하기 (오버라이딩)
/// </summary>
/// <param name="finalSize">최종 크기</param>
/// <returns>최종 크기</returns>
protected override Size ArrangeOverride(Size finalSize)
{
this.border.Arrange(new Rect(new Point(0, 0), finalSize));
return finalSize;
}
#endregion
#region 마우스 ENTER 처리하기 - OnMouseEnter(e)
/// <summary>
/// 마우스 ENTER 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnMouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
if(this.highlightedColorCell != null)
{
this.highlightedColorCell.IsHighlighted = false;
this.highlightedColorCell = null;
}
}
#endregion
#region 마우스 이동시 처리하기 - OnMouseMove(e)
/// <summary>
/// 마우스 이동시 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
ColorCell colorCell = e.Source as ColorCell;
if(colorCell != null)
{
if(this.highlightedColorCell != null)
{
this.highlightedColorCell.IsHighlighted = false;
}
this.highlightedColorCell = colorCell;
this.highlightedColorCell.IsHighlighted = true;
}
}
#endregion
#region 마우스 DOWN 처리하기 - OnMouseDown(e)
/// <summary>
/// 마우스 DOWN 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
ColorCell colorCell = e.Source as ColorCell;
if(colorCell != null)
{
if(this.selectedColorCell != null)
{
this.selectedColorCell.IsSelected = false;
}
this.selectedColorCell = colorCell;
this.selectedColorCell.IsSelected = true;
}
Focus();
}
#endregion
#region 마우스 UP 처리하기 - OnMouseUp(e)
/// <summary>
/// 마우스 UP 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
ColorCell colorCell = e.Source as ColorCell;
if(colorCell != null)
{
if(this.selectedColorCell != null)
{
this.selectedColorCell.IsSelected = false;
}
this.selectedColorCell = colorCell;
this.selectedColorCell.IsSelected = true;
this.selectedColor = (this.selectedColorCell.Brush as SolidColorBrush).Color;
OnSelectedColorChanged(EventArgs.Empty);
}
}
#endregion
#region 마우스 LEAVE 처리하기 - OnMouseLeave(e)
/// <summary>
/// 마우스 LEAVE 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnMouseLeave(MouseEventArgs e)
{
base.OnMouseLeave(e);
if(this.highlightedColorCell != null)
{
this.highlightedColorCell.IsHighlighted = false;
this.highlightedColorCell = null;
}
}
#endregion
#region 키보드 포커스 획득시 처리하기 - OnGotKeyboardFocus(e)
/// <summary>
/// 키보드 포커스 획득시 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);
if(this.highlightedColorCell == null)
{
if(this.selectedColorCell != null)
{
this.highlightedColorCell = this.selectedColorCell;
}
else
{
this.highlightedColorCell = this.colorCellArray[0, 0];
}
this.highlightedColorCell.IsHighlighted = true;
}
}
#endregion
#region 키 DOWN 처리하기 - OnKeyDown(e)
/// <summary>
/// 키 DOWN 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
int index = this.uniformGrid.Children.IndexOf(this.highlightedColorCell);
int y = index / COLUMN_COUNT;
int x = index % COLUMN_COUNT;
switch(e.Key)
{
case Key.Home :
y = 0;
x = 0;
break;
case Key.End :
y = ROW_COUNT - 1;
x = COLUMN_COUNT + 1;
break;
case Key.Down :
if((y = (y + 1) % ROW_COUNT) == 0)
{
x++;
}
break;
case Key.Up :
if((y = (y + ROW_COUNT - 1) % ROW_COUNT) == ROW_COUNT - 1)
{
x--;
}
break;
case Key.Right :
if((x = (x + 1) % COLUMN_COUNT) == 0)
{
y++;
}
break;
case Key.Left :
if((x = (x + COLUMN_COUNT - 1) % COLUMN_COUNT) == COLUMN_COUNT - 1)
{
y--;
}
break;
case Key.Enter :
case Key.Space :
if(this.selectedColorCell != null)
{
this.selectedColorCell.IsSelected = false;
}
this.selectedColorCell = this.highlightedColorCell;
this.selectedColorCell.IsSelected = true;
this.selectedColor = (this.selectedColorCell.Brush as SolidColorBrush).Color;
OnSelectedColorChanged(EventArgs.Empty);
break;
default :
return;
}
if(x >= COLUMN_COUNT || y >= ROW_COUNT)
{
MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
else if(x < 0 || y < 0)
{
MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
}
else
{
this.highlightedColorCell.IsHighlighted = false;
this.highlightedColorCell = this.colorCellArray[y, x];
this.highlightedColorCell.IsHighlighted = true;
}
e.Handled = true;
}
#endregion
#region 키보드 포커스 상실시 처리하기 - OnLostKeyboardFocus(e)
/// <summary>
/// 키보드 포커스 상실시 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);
if(this.highlightedColorCell != null)
{
this.highlightedColorCell.IsHighlighted = false;
this.highlightedColorCell = null;
}
}
#endregion
#region 선택 색상 변경시 처리하기 - OnSelectedColorChanged(e)
/// <summary>
/// 선택 색상 변경시 처리하기
/// </summary>
/// <param name="e">이벤트 발생자</param>
protected virtual void OnSelectedColorChanged(EventArgs e)
{
if(SelectedColorChanged != null)
{
SelectedColorChanged(this, e);
}
}
#endregion
}
}
300x250
▶ MainWindow.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public class MainWindow : Window
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
SizeToContent = SizeToContent.WidthAndHeight;
Padding = new Thickness(10);
FontFamily = new FontFamily("나눔고딕코딩");
FontSize = 16;
Title = "Control 클래스 : 색상 그리드 사용하기";
StackPanel stackPanel = new StackPanel();
stackPanel.Orientation = Orientation.Horizontal;
Content = stackPanel;
Button button1 = new Button();
button1.Content = "테스트 버튼";
button1.Margin = new Thickness(24);
button1.HorizontalAlignment = HorizontalAlignment.Center;
button1.VerticalAlignment = VerticalAlignment.Center;
stackPanel.Children.Add(button1);
ColorGrid colorGrid = new ColorGrid();
colorGrid.Margin = new Thickness(24);
colorGrid.HorizontalAlignment = HorizontalAlignment.Center;
colorGrid.VerticalAlignment = VerticalAlignment.Center;
colorGrid.SelectedColorChanged += colorGrid_SelectedColorChanged;
stackPanel.Children.Add(colorGrid);
Button button2 = new Button();
button2.Content = "테스트 버튼";
button2.Margin = new Thickness(24);
button2.HorizontalAlignment = HorizontalAlignment.Center;
button2.VerticalAlignment = VerticalAlignment.Center;
stackPanel.Children.Add(button2);
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 프로그램 시작하기 - Main()
/// <summary>
/// 프로그램 시작하기
/// </summary>
[STAThread]
private static void Main()
{
Application application = new Application();
application.Run(new MainWindow());
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Private
#region 색상 그리드 선택 색상 변경시 처리하기 - colorGrid_SelectedColorChanged(sender, e)
/// <summary>
/// 색상 그리드 선택 색상 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void colorGrid_SelectedColorChanged(object sender, EventArgs e)
{
ColorGrid colorGrid = sender as ColorGrid;
Background = new SolidColorBrush(colorGrid.SelectedColor);
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] 폴더 컨테이너 사용하기 (0) | 2019.04.16 |
---|---|
[C#/WPF] SystemParameters 클래스 : 윈도우 위치 설정하기 (0) | 2019.04.15 |
[C#/WPF] ListBox 클래스 : 3차원 큐브 리스트 박스 사용하기 (0) | 2019.04.13 |
[C#/WPF] DataGrid 클래스 : 엑셀 파일 내보내기 (0) | 2019.04.13 |
[C#/WPF] ListBox 클래스 : 색상 그리드 박스 사용하기 (0) | 2019.04.12 |
[C#/WPF] ListBox 클래스 : 색상 리스트 박스 사용하기 (0) | 2019.04.12 |
[C#/WPF] Uri 클래스 : 리소스 사용하기 (0) | 2019.04.12 |
[C#/WPF] Viewport3D 클래스 사용하기 (0) | 2019.04.12 |
[C#/WPF] VisualStateManager 엘리먼트 사용하기 (0) | 2019.04.12 |
[C#/WPF] XpsDocument 클래스 : XPS 문서 사용하기 (0) | 2019.04.12 |
댓글을 달아 주세요