728x90
반응형
728x170
▶ CommandManager.cs
using System;
using System.Collections.Generic;
namespace TestProject
{
/// <summary>
/// 명령 관리자
/// </summary>
public class CommandManager
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 약한 참조 핸들러 추가하기 - AddWeakReferenceHandler(weakReferenceList, eventHandler)
/// <summary>
/// 약한 참조 핸들러 추가하기
/// </summary>
/// <param name="weakReferenceList">약한 참조 리스트</param>
/// <param name="eventHandler">이벤트 핸들러</param>
public static void AddWeakReferenceHandler(ref List<WeakReference> weakReferenceList, EventHandler eventHandler)
{
if(weakReferenceList == null)
{
weakReferenceList = new List<WeakReference>();
}
weakReferenceList.Add(new WeakReference(eventHandler));
}
#endregion
#region 약한 참조 핸들러 제거하기 - RemoveWeakReferenceHandler(weakReferenceList, eventHandler)
/// <summary>
/// 약한 참조 핸들러 제거하기
/// </summary>
/// <param name="weakReferenceList">약한 참조 리스트</param>
/// <param name="eventHandler">이벤트 핸들러</param>
public static void RemoveWeakReferenceHandler(List<WeakReference> weakReferenceList, EventHandler eventHandler)
{
if(weakReferenceList != null)
{
for(int i = weakReferenceList.Count - 1; i >= 0; i--)
{
WeakReference weakReference = weakReferenceList[i];
EventHandler existingEventHandler = weakReference.Target as EventHandler;
if((existingEventHandler == null) || (existingEventHandler == eventHandler))
{
weakReferenceList.RemoveAt(i);
}
}
}
}
#endregion
#region 약한 참조 핸들러 호출하기 - CallWeakReferenceHandlers(weakReferenceList)
/// <summary>
/// 약한 참조 핸들러 호출하기
/// </summary>
/// <param name="weakReferenceList">약한 참조 리스트</param>
public static void CallWeakReferenceHandlers(List<WeakReference> weakReferenceList)
{
if(weakReferenceList != null)
{
EventHandler[] eventHandlerArray = new EventHandler[weakReferenceList.Count];
int count = 0;
for(int i = weakReferenceList.Count - 1; i >= 0; i--)
{
WeakReference weakReference = weakReferenceList[i];
EventHandler eventHandler = weakReference.Target as EventHandler;
if(eventHandler == null)
{
weakReferenceList.RemoveAt(i);
}
else
{
eventHandlerArray[count] = eventHandler;
count++;
}
}
for(int i = 0; i < count; i++)
{
EventHandler eventHandler = eventHandlerArray[i];
eventHandler(null, EventArgs.Empty);
}
}
}
#endregion
}
}
728x90
▶ DelegateCommand.cs
using System;
using System.Collections.Generic;
using System.Windows.Input;
namespace TestProject
{
/// <summary>
/// 대리자 명령
/// </summary>
public class DelegateCommand : ICommand
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Event
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 실행 가능 여부 변경시 이벤트 - CanExecuteChanged
/// <summary>
/// 실행 가능 여부 변경시 이벤트
/// </summary>
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.AddWeakReferenceHandler(ref this.weakReferenceList, value);
}
remove
{
CommandManager.RemoveWeakReferenceHandler(this.weakReferenceList, value);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 실행 액션
/// </summary>
private readonly Action executeAction;
/// <summary>
/// 실행 가능 여부 함수
/// </summary>
private readonly Func<bool> canExecuteFunction;
/// <summary>
/// 약한 참조 리스트
/// </summary>
private List<WeakReference> weakReferenceList;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - DelegateCommand(executeAction, canExecuteFunction)
/// <summary>
/// 생성자
/// </summary>
/// <param name="executeAction">실행 액션</param>
/// <param name="canExecuteFunction">실행 가능 여부 함수</param>
public DelegateCommand(Action executeAction, Func<bool> canExecuteFunction)
{
if(executeAction == null)
{
throw new ArgumentNullException("executeAction");
}
this.executeAction = executeAction;
this.canExecuteFunction = canExecuteFunction;
}
#endregion
#region 생성자 - DelegateCommand(executeAction)
/// <summary>
/// 생성자
/// </summary>
/// <param name="executeAction">실행 액션</param>
public DelegateCommand(Action executeAction) : this(executeAction, null)
{
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 실행 가능 여부 구하기 - CanExecute()
/// <summary>
/// 실행 가능 여부 구하기
/// </summary>
/// <returns>실행 가능 여부</returns>
public bool CanExecute()
{
if(this.canExecuteFunction != null)
{
return this.canExecuteFunction();
}
return true;
}
#endregion
#region 실행 가능 여부 구하기 - ICommand.CanExecute(parameter)
/// <summary>
/// 실행 가능 여부 구하기
/// </summary>
/// <param name="parameter">매개 변수</param>
/// <returns>실행 가능 여부</returns>
bool ICommand.CanExecute(object parameter)
{
return CanExecute();
}
#endregion
#region 실행하기 - Execute()
/// <summary>
/// 실행하기
/// </summary>
public void Execute()
{
if(this.executeAction != null)
{
this.executeAction();
}
}
#endregion
#region 실행하기 - ICommand.Execute(parameter)
/// <summary>
/// 실행하기
/// </summary>
/// <param name="parameter">매개 변수</param>
void ICommand.Execute(object parameter)
{
Execute();
}
#endregion
#region 실행 가능 여부 변경시 이벤트 발생시키기 - RaiseCanExecuteChangedEvent()
/// <summary>
/// 실행 가능 여부 변경시 이벤트 발생시키기
/// </summary>
public void RaiseCanExecuteChangedEvent()
{
FireCanExecuteChangedEvent();
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 실행 가능 여부 변경시 이벤트 발생시키기 - FireCanExecuteChangedEvent()
/// <summary>
/// 실행 가능 여부 변경시 이벤트 발생시키기
/// </summary>
protected virtual void FireCanExecuteChangedEvent()
{
CommandManager.CallWeakReferenceHandlers(this.weakReferenceList);
}
#endregion
}
}
300x250
▶ CircularProgressBar.xaml
<UserControl x:Class="TestProject.CircularProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="45"
Height="45"
Background="Transparent">
<UserControl.Resources>
<SolidColorBrush x:Key="EllipseSolidColorBrushKey"
Color="#ff2e6187" />
</UserControl.Resources>
<Viewbox
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="40"
Height="40">
<Grid
VerticalAlignment="Center"
HorizontalAlignment="Center"
Background="Transparent">
<Canvas Name="canvas"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="120"
Height="120"
RenderTransformOrigin="0.5 0.5">
<Ellipse Name="ellipse0" Canvas.Left="0" Canvas.Top="0"
Width="20"
Height="20"
Stretch="Fill"
Opacity="1.0"
Fill="{StaticResource EllipseSolidColorBrushKey}" />
<Ellipse Name="ellipse1" Canvas.Left="0" Canvas.Top="0"
Width="20"
Height="20"
Stretch="Fill"
Opacity="0.9"
Fill="{StaticResource EllipseSolidColorBrushKey}" />
<Ellipse Name="ellipse2" Canvas.Left="0" Canvas.Top="0"
Width="20"
Height="20"
Stretch="Fill"
Opacity="0.8"
Fill="{StaticResource EllipseSolidColorBrushKey}" />
<Ellipse Name="ellipse3" Canvas.Left="0" Canvas.Top="0"
Width="20"
Height="20"
Stretch="Fill"
Opacity="0.7"
Fill="{StaticResource EllipseSolidColorBrushKey}" />
<Ellipse Name="ellipse4" Canvas.Left="0" Canvas.Top="0"
Width="20"
Height="20"
Stretch="Fill"
Opacity="0.6"
Fill="{StaticResource EllipseSolidColorBrushKey}" />
<Ellipse Name="ellipse5" Canvas.Left="0" Canvas.Top="0"
Width="20"
Height="20"
Stretch="Fill"
Opacity="0.5"
Fill="{StaticResource EllipseSolidColorBrushKey}" />
<Ellipse Name="ellipse6" Canvas.Left="0" Canvas.Top="0"
Width="20"
Height="20"
Stretch="Fill"
Opacity="0.4"
Fill="{StaticResource EllipseSolidColorBrushKey}" />
<Ellipse Name="ellipse7" Canvas.Left="0" Canvas.Top="0"
Width="20"
Height="20"
Stretch="Fill"
Opacity="0.3"
Fill="{StaticResource EllipseSolidColorBrushKey}" />
<Ellipse Name="ellipse8" Canvas.Left="0" Canvas.Top="0"
Width="20"
Height="20"
Stretch="Fill"
Opacity="0.2"
Fill="{StaticResource EllipseSolidColorBrushKey}" />
<Canvas.RenderTransform>
<RotateTransform x:Name="rotateTransform"
Angle="0" />
</Canvas.RenderTransform>
</Canvas>
</Grid>
</Viewbox>
</UserControl>
반응형
▶ CircularProgressBar.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace TestProject
{
/// <summary>
/// 환형 진행바
/// </summary>
public partial class CircularProgressBar : UserControl
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 최소값 속성 - MinimumProperty
/// <summary>
/// 최소값 속성
/// </summary>
public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register
(
"Minimum",
typeof(int),
typeof(CircularProgressBar),
new UIPropertyMetadata(1)
);
#endregion
#region 최대값 속성 - MaximumProperty
/// <summary>
/// 최대값 속성
/// </summary>
public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register
(
"Maximum",
typeof(int),
typeof(CircularProgressBar),
new UIPropertyMetadata(1)
);
#endregion
#region 값 속성 - ValueProperty
/// <summary>
/// 값 속성
/// </summary>
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register
(
"Value",
typeof(int),
typeof(CircularProgressBar),
new UIPropertyMetadata(100)
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 디스패처 타이머
/// </summary>
private readonly DispatcherTimer dispatcherTimer;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 최소값 - Minimum
/// <summary>
/// 최소값
/// </summary>
public int Minimum
{
get
{
return (int)GetValue(MinimumProperty);
}
set
{
SetValue(MinimumProperty, value);
}
}
#endregion
#region 최대값 - Maximum
/// <summary>
/// 최대값
/// </summary>
public int Maximum
{
get
{
return (int)GetValue(MaximumProperty);
}
set
{
SetValue(MaximumProperty, value);
}
}
#endregion
#region 값 - Value
/// <summary>
/// 값
/// </summary>
public int Value
{
get
{
return (int)GetValue(ValueProperty);
}
set
{
SetValue(ValueProperty, value);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - CircularProgressBar()
/// <summary>
/// 생성자
/// </summary>
public CircularProgressBar()
{
InitializeComponent();
this.dispatcherTimer = new DispatcherTimer(DispatcherPriority.ContextIdle, Dispatcher)
{
Interval = new TimeSpan(0, 0, 0, 0, 75)
};
IsVisibleChanged += UserControl_IsVisibleChanged;
this.canvas.Loaded += canvas_Loaded;
this.canvas.Unloaded += canvas_Unloaded;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 위치 설정하기 - SetPosition(dependencyObject, offset, indexOffSet, step)
/// <summary>
/// 위치 설정하기
/// </summary>
/// <param name="dependencyObject">의존 객체</param>
/// <param name="offset">오프셋</param>
/// <param name="indexOffSet">인덱스 오프셋</param>
/// <param name="step">단계</param>
private static void SetPosition(DependencyObject dependencyObject, double offset, double indexOffSet, double step)
{
dependencyObject.SetValue(Canvas.LeftProperty, 50 + (Math.Sin(offset + (indexOffSet * step)) * 50));
dependencyObject.SetValue(Canvas.TopProperty , 50 + (Math.Cos(offset + (indexOffSet * step)) * 50));
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Private
////////////////////////////////////////////////////////////////////// Event
#region 사용자 컨트롤 표시 여부 변경시 처리하기 - UserControl_IsVisibleChanged(sender, e)
/// <summary>
/// 사용자 컨트롤 표시 여부 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
bool isVisible = (bool)e.NewValue;
if(isVisible)
{
Start();
}
else
{
Stop();
}
}
#endregion
#region 캔버스 로드시 처리하기 - canvas_Loaded(sender, e)
/// <summary>
/// 캔버스 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void canvas_Loaded(object sender, RoutedEventArgs e)
{
const double offset = Math.PI;
const double step = Math.PI * 2 / 10.0;
SetPosition(this.ellipse0, offset, 0.0, step);
SetPosition(this.ellipse1, offset, 1.0, step);
SetPosition(this.ellipse2, offset, 2.0, step);
SetPosition(this.ellipse3, offset, 3.0, step);
SetPosition(this.ellipse4, offset, 4.0, step);
SetPosition(this.ellipse5, offset, 5.0, step);
SetPosition(this.ellipse6, offset, 6.0, step);
SetPosition(this.ellipse7, offset, 7.0, step);
SetPosition(this.ellipse8, offset, 8.0, step);
}
#endregion
#region 캔버스 언로드시 처리하기 - canvas_Unloaded(sender, e)
/// <summary>
/// 캔버스 언로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void canvas_Unloaded(object sender, RoutedEventArgs e)
{
Stop();
}
#endregion
#region 디스패처 타이머 틱 처리하기 - dispatcherTimer_Tick(sender, e)
/// <summary>
/// 디스패처 타이머 틱 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
this.rotateTransform.Angle = (this.rotateTransform.Angle + 36) % 360;
}
#endregion
////////////////////////////////////////////////////////////////////// Function
#region 시작하기 - Start()
/// <summary>
/// 시작하기
/// </summary>
private void Start()
{
this.dispatcherTimer.Tick += dispatcherTimer_Tick;
this.dispatcherTimer.Start();
}
#endregion
#region 중단하기 - Stop()
/// <summary>
/// 중단하기
/// </summary>
private void Stop()
{
this.dispatcherTimer.Stop();
this.dispatcherTimer.Tick -= dispatcherTimer_Tick;
}
#endregion
}
}
▶ LoadingPanel.xaml
<UserControl x:Class="TestProject.LoadingPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestProject"
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Classic">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverterKey" />
<LinearGradientBrush x:Key="PanelBackgroundLinearGradientBrushKey"
StartPoint="0.5 0"
EndPoint="0.5 1">
<GradientStop Offset="0" Color="#ff1b1b1b" />
<GradientStop Offset="1" Color="Black" />
</LinearGradientBrush>
<Style x:Key="BasicButtonStyleKey" TargetType="{x:Type Button}">
<Setter Property="BorderThickness" Value="3" />
<Setter Property="BorderBrush" Value="{x:Static theme:ClassicBorderDecorator.ClassicBorderBrush}" />
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Padding" Value="0 0 1 1" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<theme:ClassicBorderDecorator Name="ContentContainer"
BorderStyle="None"
BorderThickness="0"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
RecognizesAccessKey="True" />
</theme:ClassicBorderDecorator>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter
TargetName="ContentContainer"
Property="BorderStyle"
Value="RaisedFocused" />
</Trigger>
<Trigger Property="IsDefaulted" Value="True">
<Setter
TargetName="ContentContainer"
Property="BorderStyle"
Value="RaisedFocused" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter
TargetName="ContentContainer"
Property="BorderStyle"
Value="RaisedPressed" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter
TargetName="ContentContainer"
Property="BorderStyle"
Value="RaisedPressed" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CloseButtonStyleKey" BasedOn="{StaticResource BasicButtonStyleKey}" TargetType="Button">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Margin" Value="15,7" />
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="Verdana" />
<Setter Property="FontSize" Value="9" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style x:Key="MessageTextBlockStyleKey" TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Margin" Value="0 11 0 0" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="TextWrapping" Value="WrapWithOverflow" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style x:Key="SubsidaryMessageTextBlockStyleKey" TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Margin" Value="0,5" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="FontSize" Value="12" />
</Style>
</UserControl.Resources>
<DockPanel Background="{StaticResource PanelBackgroundLinearGradientBrushKey}"
Visibility="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}},
Path=IsLoading,
Mode=OneWay,
Converter={StaticResource BooleanToVisibilityConverterKey}}">
<Path DockPanel.Dock="Top"
Margin="0 0.25 0 0"
Height="1"
Stretch="Fill"
Stroke="Black"
Data="M 0 44.956 L 312.00641 44.956" />
<Path DockPanel.Dock="Top"
Margin="0 0.25 0 0"
Height="1"
Stretch="Fill"
Stroke="#ff2f2f2f"
Data="M 0 44.956 L 312.00641 44.956" />
<Button Name="closeBitton" DockPanel.Dock="Right"
Style="{StaticResource CloseButtonStyleKey}"
ToolTip="Close"
Content="Close X" />
<local:CircularProgressBar DockPanel.Dock="Left"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="18 10"
Height="45" />
<StackPanel VerticalAlignment="Top">
<TextBlock
Style="{StaticResource MessageTextBlockStyleKey}"
Foreground="#ffa1c3d2"
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=Message}" />
<TextBlock
Style="{StaticResource SubsidaryMessageTextBlockStyleKey}"
Foreground="#ffa1c3d2"
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=SubsidaryMessage}" />
</StackPanel>
</DockPanel>
</UserControl>
▶ LoadingPanel.xaml.cs
using System.Windows;
using System.Windows.Input;
namespace TestProject
{
/// <summary>
/// 로딩 패널
/// </summary>
public partial class LoadingPanel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 로딩 여부 속성 - IsLoadingProperty
/// <summary>
/// 로딩 여부 속성
/// </summary>
public static readonly DependencyProperty IsLoadingProperty = DependencyProperty.Register
(
"IsLoading",
typeof(bool),
typeof(LoadingPanel),
new UIPropertyMetadata(false)
);
#endregion
#region 메시지 속성 - MessageProperty
/// <summary>
/// 메시지 속성
/// </summary>
public static readonly DependencyProperty MessageProperty = DependencyProperty.Register
(
"Message",
typeof(string),
typeof(LoadingPanel),
new UIPropertyMetadata("로딩중...")
);
#endregion
#region 보조 메시지 속성 - SubsidaryMessageProperty
/// <summary>
/// 보조 메시지 속성
/// </summary>
public static readonly DependencyProperty SubsidaryMessageProperty = DependencyProperty.Register
(
"SubsidaryMessage",
typeof(string),
typeof(LoadingPanel),
new UIPropertyMetadata(string.Empty)
);
#endregion
#region 패널 닫기 명령 속성 - ClosePanelCommandProperty
/// <summary>
/// 패널 닫기 명령 속성
/// </summary>
public static readonly DependencyProperty ClosePanelCommandProperty = DependencyProperty.Register
(
"ClosePanelCommand",
typeof(ICommand),
typeof(LoadingPanel)
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 로딩 여부 - IsLoading
/// <summary>
/// 로딩 여부
/// </summary>
public bool IsLoading
{
get
{
return (bool)GetValue(IsLoadingProperty);
}
set
{
SetValue(IsLoadingProperty, value);
}
}
#endregion
#region 메시지 - Message
/// <summary>
/// 메시지
/// </summary>
public string Message
{
get
{
return (string)GetValue(MessageProperty);
}
set
{
SetValue(MessageProperty, value);
}
}
#endregion
#region 보조 메시지 - SubsidaryMessage
/// <summary>
/// 보조 메시지
/// </summary>
public string SubsidaryMessage
{
get
{
return (string)GetValue(SubsidaryMessageProperty);
}
set
{
SetValue(SubsidaryMessageProperty, value);
}
}
#endregion
#region 패널 닫기 명령 - ClosePanelCommand
/// <summary>
/// 패널 닫기 명령
/// </summary>
public ICommand ClosePanelCommand
{
get
{
return (ICommand)GetValue(ClosePanelCommandProperty);
}
set
{
SetValue(ClosePanelCommandProperty, value);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - LoadingPanel()
/// <summary>
/// 생성자
/// </summary>
public LoadingPanel()
{
InitializeComponent();
this.closeBitton.Click += closeButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 닫기 버튼 클릭시 처리하기 - closeButton_Click(sender, e)
/// <summary>
/// 닫기 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void closeButton_Click(object sender, RoutedEventArgs e)
{
ClosePanelCommand?.Execute(null);
}
#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"
Width="800"
Height="600"
Title="UserControl 클래스 : 로딩 패널 사용하기"
Background="Orange"
FontFamily="나눔고딕코딩"
FontSize="16">
<Grid>
<DockPanel
HorizontalAlignment="Center"
VerticalAlignment="Top">
<StackPanel
Margin="10"
Orientation="Horizontal">
<Button Name="btnShow"
Width="100"
Height="30"
Content="패널 표시"
Command="{Binding ShowPanelCommand}" />
<Button Name="btnHide"
Margin="10 0 0 0"
Width="100"
Height="30"
Content="패널 숨김"
Command="{Binding HidePanelCommand}" />
<Button Name="btnChange"
Width="100"
Margin="10 0 0 0"
Height="30"
Content="메시지 변경"
Command="{Binding ChangeMessageCommand}" />
</StackPanel>
</DockPanel>
<Grid VerticalAlignment="Bottom">
<local:LoadingPanel
IsLoading="{Binding IsPanelLoading}"
Message="{Binding PanelMessage}"
SubsidaryMessage="{Binding PanelSubsidaryMessage}"
ClosePanelCommand="{Binding PanelCloseCommand}" />
</Grid>
</Grid>
</Window>
▶ MainWindow.xaml.cs
using System;
using System.ComponentModel;
using System.Windows.Input;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public partial class MainWindow : INotifyPropertyChanged
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Event
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 속성 변경시 이벤트 - PropertyChanged
/// <summary>
/// 속성 변경시 이벤트
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 패널 로딩 여부
/// </summary>
private bool isPanelLoading;
/// <summary>
/// 패널 메시지
/// </summary>
private string panelMessage = "패널 메시지";
/// <summary>
/// 패널 보조 메시지
/// </summary>
private string panelSubsidaryMessage = "패널 보조 메시지";
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 패널 표시 명령 - ShowPanelCommand
/// <summary>
/// 패널 표시 명령
/// </summary>
public ICommand ShowPanelCommand
{
get
{
return new DelegateCommand(() => { IsPanelLoading = true; });
}
}
#endregion
#region 패널 숨김 명령 - HidePanelCommand
/// <summary>
/// 패널 숨김 명령
/// </summary>
public ICommand HidePanelCommand
{
get
{
return new DelegateCommand(() => { IsPanelLoading = false; });
}
}
#endregion
#region 메시지 변경 명령 - ChangeMessageCommand
/// <summary>
/// 메시지 변경 명령
/// </summary>
public ICommand ChangeMessageCommand
{
get
{
return new DelegateCommand(() => { PanelSubsidaryMessage = $"메시지 : {DateTime.Now}"; });
}
}
#endregion
#region 패널 로딩 여부 - IsPanelLoading
/// <summary>
/// 패널 로딩 여부
/// </summary>
public bool IsPanelLoading
{
get
{
return this.isPanelLoading;
}
set
{
this.isPanelLoading = value;
FirePropertyChangedEvent("IsPanelLoading");
}
}
#endregion
#region 패널 메시지 - PanelMessage
/// <summary>
/// 패널 메시지
/// </summary>
public string PanelMessage
{
get
{
return this.panelMessage;
}
set
{
this.panelMessage = value;
FirePropertyChangedEvent("PanelMessage");
}
}
#endregion
#region 패널 보조 메시지 - PanelSubsidaryMessage
/// <summary>
/// 패널 보조 메시지
/// </summary>
public string PanelSubsidaryMessage
{
get
{
return this.panelSubsidaryMessage;
}
set
{
this.panelSubsidaryMessage = value;
FirePropertyChangedEvent("PanelSubsidaryMessage");
}
}
#endregion
#region 패널 닫기 명령 - PanelCloseCommand
/// <summary>
/// 패널 닫기 명령
/// </summary>
public ICommand PanelCloseCommand
{
get
{
return new DelegateCommand(() => { IsPanelLoading = false; });
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 속성 변경시 이벤트 발생시키기 - FirePropertyChangedEvent(propertyName)
/// <summary>
/// 속성 변경시 이벤트 발생시키기
/// </summary>
/// <param name="propertyName">속성명</param>
protected void FirePropertyChangedEvent(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] 확장 메뉴 사용하기 (0) | 2021.09.15 |
---|---|
[C#/WPF] ToggleButton 클래스 : 드롭 다운 버튼/분리 버튼 사용하기 (0) | 2021.09.14 |
[C#/WPF] 열거형 정렬하기 (0) | 2021.09.13 |
[C#/WPF] UserControl 엘리먼트 : 로딩 패널 사용하기 (0) | 2021.09.13 |
[C#/WPF] Adorner 클래스 : 슬라이딩 어도너 사용하기 (0) | 2021.09.13 |
[C#/WPF] ImageAwesome 엘리먼트 : Spin/SpinDuration 속성을 사용해 아이콘 회전시키기 (0) | 2021.09.11 |
[C#/WPF] 누겟 설치 : FontAwesome.WPF (0) | 2021.09.11 |
[C#/WPF] GOM 플레이어 모방하기 (0) | 2021.09.05 |
[C#/WPF] LinearGradientBrush 엘리먼트 사용하기 (0) | 2021.08.24 |
[C#/WPF] Vector 구조체 : 각도에서 벡터 구하기 (0) | 2021.08.20 |
댓글을 달아 주세요