728x90
반응형
728x170
▶ ListBoxItemSlideDirection.cs
namespace TestProject
{
/// <summary>
/// 리스트 박스 항목 슬라이드 방향
/// </summary>
public enum ListBoxItemSlideDirection
{
/// <summary>
/// 왼쪽
/// </summary>
Left,
/// <summary>
/// 위쪽
/// </summary>
Up,
/// <summary>
/// 오른쪽
/// </summary>
Right,
/// <summary>
/// 아래쪽
/// </summary>
Down
}
}
728x90
▶ SlidingListBox.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace TestProject
{
/// <summary>
/// 슬라이딩 리스트 박스
/// </summary>
public class SlidingListBox : ListBox
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 슬라이드 방향 속성 - SlideDirectionProperty
/// <summary>
/// 슬라이드 방향 속성
/// </summary>
public static readonly DependencyProperty SlideDirectionProperty = DependencyProperty.Register
(
"SlideDirection",
typeof(ListBoxItemSlideDirection),
typeof(SlidingListBox),
new UIPropertyMetadata(ListBoxItemSlideDirection.Right)
);
#endregion
#region 슬라이드 거리 속성 - SlideDistanceProperty
/// <summary>
/// 슬라이드 거리 속성
/// </summary>
public static readonly DependencyProperty SlideDistanceProperty = DependencyProperty.Register
(
"SlideDistance",
typeof(double),
typeof(SlidingListBox),
new UIPropertyMetadata
(
20.0,
NumericPropertyChangedCallback<double>
)
);
#endregion
#region 슬라이드 지속 시간 속성 - SlideDurationProperty
/// <summary>
/// 슬라이드 지속 시간 속성
/// </summary>
public static readonly DependencyProperty SlideDurationProperty = DependencyProperty.Register
(
"SlideDuration",
typeof(int),
typeof(SlidingListBox),
new UIPropertyMetadata
(
200,
NumericPropertyChangedCallback<int>
)
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 슬라이드 방향 - SlideDirection
/// <summary>
/// 슬라이드 방향
/// </summary>
public ListBoxItemSlideDirection SlideDirection
{
get
{
return (ListBoxItemSlideDirection)GetValue(SlideDirectionProperty);
}
set
{
SetValue(SlideDirectionProperty, value);
}
}
#endregion
#region 슬라이드 거리 - SlideDistance
/// <summary>
/// 슬라이드 거리
/// </summary>
public double SlideDistance
{
get
{
return (double)GetValue(SlideDistanceProperty);
}
set
{
SetValue(SlideDistanceProperty, value);
}
}
#endregion
#region 슬라이드 지속 시간 - SlideDuration
/// <summary>
/// 슬라이드 지속 시간
/// </summary>
public int SlideDuration
{
get
{
return (int)GetValue(SlideDurationProperty);
}
set
{
SetValue(SlideDurationProperty, value);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 숫자 속성 변경시 콜백 처리하기 - NumericPropertyChangedCallback<T>(d, e)
/// <summary>
/// 숫자 속성 변경시 콜백 처리하기
/// </summary>
/// <typeparam name="T">속성 타입</typeparam>
/// <param name="d">의존 객체</param>
/// <param name="e">이벤트 인자</param>
private static void NumericPropertyChangedCallback<T>(DependencyObject d, DependencyPropertyChangedEventArgs e) where T : IComparable
{
if(((T)e.NewValue).CompareTo(default(T)) < 0)
{
throw new ArgumentOutOfRangeException(e.Property.Name);
}
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Protected
#region 선택 변경시 처리하기 - OnSelectionChanged(e)
/// <summary>
/// 선택 변경시 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
ItemContainerGenerator generator = this.ItemContainerGenerator;
if(generator.Status != GeneratorStatus.ContainersGenerated)
{
return;
}
for(int i = 0; i < Items.Count; ++i)
{
ListBoxItem item = generator.ContainerFromIndex(i) as ListBoxItem;
if(VisualTreeHelper.GetChildrenCount(item) == 0)
{
continue;
}
Border rootBorder = VisualTreeHelper.GetChild(item, 0) as Border;
if(rootBorder == null)
{
continue;
}
AnimateItem(item, rootBorder);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Private
#region 항목 애니메이션 처리하기 - AnimateItem(item, rootBorder)
/// <summary>
/// 항목 애니메이션 처리하기
/// </summary>
/// <param name="item">리스트 박스 항목</param>
/// <param name="rootBorder">루트 Border</param>
private void AnimateItem(ListBoxItem item, Border rootBorder)
{
Thickness thickness;
if(item.IsSelected)
{
ListBoxItemSlideDirection direction = this.SlideDirection;
if(direction == ListBoxItemSlideDirection.Up)
{
thickness = new Thickness(2, 0, 0, this.SlideDistance);
}
else if(direction == ListBoxItemSlideDirection.Right)
{
thickness = new Thickness(2 + this.SlideDistance, 0, 0, 0);
}
else if(direction == ListBoxItemSlideDirection.Down)
{
thickness = new Thickness(2, this.SlideDistance, 0, 0);
}
else
{
thickness = new Thickness(2, 0, this.SlideDistance, 0);
}
}
else
{
thickness = new Thickness(2, 0, 0, 0);
}
TimeSpan timeSpan = TimeSpan.FromMilliseconds(this.SlideDuration);
Duration duration = new Duration(timeSpan);
ThicknessAnimation animation = new ThicknessAnimation(thickness, duration);
rootBorder.BeginAnimation(Border.PaddingProperty, animation);
}
#endregion
}
}
300x250
▶ 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="ListBox 클래스 : 항목 선택시 슬라이딩 리스트 박스 사용하기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Window.Resources>
<LinearGradientBrush x:Key="BackgroundLinearGradientBrushKey"
StartPoint="0.5 0"
EndPoint="0.5 1">
<GradientStop Offset="0" Color="#66000000" />
<GradientStop Offset="1" Color="#33000000" />
</LinearGradientBrush>
<Style x:Key="BorderStyleKey" TargetType="{x:Type Border}">
<Setter Property="Margin" Value="4" />
<Setter Property="BorderThickness" Value="0.5" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="CornerRadius" Value="4" />
<Setter Property="Background" Value="{StaticResource BackgroundLinearGradientBrushKey}" />
<Setter Property="Padding" Value="4" />
</Style>
<DataTemplate x:Key="SlidingHorizontalItemTemplateKey">
<Border
Style="{StaticResource BorderStyleKey}"
Width="200">
<TextBlock Text="{Binding}" />
</Border>
</DataTemplate>
<DataTemplate x:Key="SlidingDownItemTemplateKey">
<Rectangle
Margin="8 0"
Height="20"
Width="55"
Fill="{Binding}" />
</DataTemplate>
<DataTemplate x:Key="SlidingUpItemTemplateKey">
<TextBlock
Margin="8 0"
Width="55"
Background="{StaticResource BackgroundLinearGradientBrushKey}"
Padding="6"
TextAlignment="Center"
Text="{Binding}" />
</DataTemplate>
</Window.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="10" />
<RowDefinition Height="*" />
<RowDefinition Height="10" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<local:SlidingListBox x:Name="listBox1" Grid.Row="0" Grid.ColumnSpan="3"
ItemTemplate="{StaticResource SlidingDownItemTemplateKey}"
SelectionMode="Extended"
SlideDirection="Down"
SlideDistance="60"
SlideDuration="100"
VerticalContentAlignment="Top">
<local:SlidingListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal"
IsItemsHost="True" />
</ItemsPanelTemplate>
</local:SlidingListBox.ItemsPanel>
</local:SlidingListBox>
<local:SlidingListBox x:Name="listBox2" Grid.Row="2" Grid.Column="0"
ItemTemplate="{StaticResource SlidingHorizontalItemTemplateKey}"
SelectionMode="Extended"
SlideDirection="Right"
SlideDistance="70"
SlideDuration="90"
HorizontalContentAlignment="Left" />
<local:SlidingListBox x:Name="listBox3" Grid.Row="2" Grid.Column="2"
ItemTemplate="{StaticResource SlidingHorizontalItemTemplateKey}"
SelectionMode="Extended"
SlideDirection="Left"
SlideDistance="50"
SlideDuration="200"
HorizontalContentAlignment="Right" />
<local:SlidingListBox x:Name="listBox4" Grid.Row="4" Grid.ColumnSpan="3"
ItemTemplate="{StaticResource SlidingUpItemTemplateKey}"
SelectionMode="Extended"
SlideDirection="Up"
SlideDistance="60"
SlideDuration="100"
VerticalContentAlignment="Bottom">
<local:SlidingListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel
Orientation="Horizontal"
IsItemsHost="True" />
</ItemsPanelTemplate>
</local:SlidingListBox.ItemsPanel>
</local:SlidingListBox>
</Grid>
</Window>
▶ MainWindow.xaml.cs
using System.Windows;
using System.Windows.Media;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public partial class MainWindow : Window
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Contructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
InitializeComponent();
Loaded += Window_Loaded;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)
/// <summary>
/// 윈도우 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Brush[] brusheArray = new SolidColorBrush[8];
for(int i = 0; i < 8; i++)
{
byte value = (byte)(255 / (i + 1) * i);
Color color = Color.FromRgb( value, value, value );
brusheArray[i] = new SolidColorBrush(color);
}
this.listBox1.ItemsSource = brusheArray;
this.listBox2.ItemsSource = new string[]
{
"Argentina",
"Brooklyn",
"Cambodia",
"Denmark",
"England",
"Fairfield",
"Germany",
"Hamburg",
"Indonesia",
};
this.listBox3.ItemsSource = new string[]
{
"Once",
"Upon",
"A",
"Time",
"There",
"Were",
"These",
"Things",
"Called",
"HWNDs..."
};
this.listBox4.ItemsSource = new int[]
{
123,
234,
345,
456,
567,
678,
789
};
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] 관리자 권한으로 실행하기 (0) | 2021.04.03 |
---|---|
[C#/WPF] 가상 키보드 사용하기 (0) | 2021.03.27 |
[C#/WPF] HTML을 XAML로 변환하기 (0) | 2021.03.20 |
[C#/WPF] LogicalTreeHelper 클래스 : GetChildren 정적 메소드를 사용해 논리적 자식 열거 가능형 구하기 (0) | 2021.03.20 |
[C#/WPF] ListBox 엘리먼트 : 마우스 진입시 애니메이션 사용하기 (0) | 2021.03.07 |
[C#/WPF] 누겟 설치 : VirtualDesktop.WPF (0) | 2021.03.06 |
[C#/WPF] SystemParameters 클래스 : VirtualScreenWidth/VirtualScreenHeight 정적 속성을 사용해 듀얼 모니터 전체 화면 윈도우 표시하기 (0) | 2021.03.06 |
[C#/WPF] Screen 클래스 : AllScreens 정적 속성을 사용해 듀얼 모니터 전체 화면 윈도우 표시하기 (0) | 2021.03.06 |
[C#/WPF] DataTemplate 엘리먼트 : Label 엘리먼트의 ContentTemplate 속성 설정하기 (0) | 2021.03.04 |
[C#/WPF] ContentPresenter 엘리먼트 사용하기 (0) | 2021.03.04 |
댓글을 달아 주세요