728x90
반응형
728x170
■ ControlTemplate 엘리먼트를 사용해 Thumb/ScrollBar/ListBoxItem 엘리먼트를 정의하는 방법을 보여준다.
▶ 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"
Width="800"
Height="600"
Title="ControlTemplate 엘리먼트 : Thumb/ScrollBar/ListBoxItem 엘리먼트 정의하기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Grid Margin="10">
<ListBox Name="listBox"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="200"
Height="350"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Padding="1 0 1 0">
<ListBox.Resources>
<Style x:Key="ScrollBarThumbKey" TargetType="{x:Type Thumb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Grid x:Name="grid">
<Rectangle
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Width="Auto"
Height="Auto"
Fill="Transparent" />
<Border x:Name="rectangle"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Width="Auto"
Height="Auto"
CornerRadius="5"
Background="{TemplateBinding Background}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Tag" Value="Horizontal">
<Setter
TargetName="rectangle"
Property="Width"
Value="Auto" />
<Setter
TargetName="rectangle"
Property="Height"
Value="7" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
<Setter Property="Width" Value="8" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="#8c8c8c" />
<Setter Property="Stylus.IsFlicksEnabled" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="rootGrid"
Width="8"
Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="0.00001*" />
</Grid.RowDefinitions>
<Track x:Name="PART_Track" Grid.Row="0"
IsDirectionReversed="true"
Focusable="false">
<Track.Thumb>
<Thumb x:Name="thumb"
Style="{DynamicResource ScrollBarThumbKey}"
Background="{TemplateBinding Foreground}" />
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton x:Name="pageUpButton"
Opacity="0"
Focusable="false"
Command="ScrollBar.PageDownCommand" />
</Track.IncreaseRepeatButton>
<Track.DecreaseRepeatButton>
<RepeatButton x:Name="pageDownButton"
Opacity="0"
Focusable="false"
Command="ScrollBar.PageUpCommand" />
</Track.DecreaseRepeatButton>
</Track>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="thumb" Property="IsMouseOver" Value="true">
<Setter
TargetName="thumb"
Property="Background"
Value="{DynamicResource ButtonSelectBrush}" />
<Setter
TargetName="thumb"
Property="Cursor"
Value="Hand" />
</Trigger>
<Trigger SourceName="thumb" Property="IsDragging" Value="true">
<Setter
TargetName="thumb"
Property="Background"
Value="{DynamicResource DarkBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter
TargetName="thumb"
Property="Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="Orientation" Value="Horizontal">
<Setter
TargetName="rootGrid"
Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-90" />
</Setter.Value>
</Setter>
<Setter
TargetName="PART_Track"
Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-90" />
</Setter.Value>
</Setter>
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="8" />
<Setter
TargetName="thumb"
Property="Tag"
Value="Horizontal" />
<Setter
TargetName="pageDownButton"
Property="Command"
Value="ScrollBar.PageLeftCommand" />
<Setter
TargetName="pageUpButton"
Property="Command"
Value="ScrollBar.PageRightCommand" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid Margin="0 5 0 5">
<Image Name="image"
Width="{Binding RelativeSource={RelativeSource AncestorType=ScrollContentPresenter, Mode=FindAncestor}, Path=ActualWidth}"
Stretch="Fill"
Source="{TemplateBinding Content}" />
<Image Name="deleteItemImage"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Width="20"
Height="20"
Source="IMAGE/deleteItem.png"
MouseDown="deleteItemImage_MouseDown" />
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="deleteItemImage" Property="IsMouseOver" Value="True">
<Setter TargetName="deleteItemImage" Property="Source" Value="IMAGE/deleteItem_over.png" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Name="addButton"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="100"
Height="30"
Content="추가" />
</Grid>
</Window>
▶ MainWindow.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public partial class MainWindow : Window
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
InitializeComponent();
this.addButton.Click += addButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 추가 버튼 클릭시 처리하기 - addButton_Click(sender, e)
/// <summary>
/// 추가 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void addButton_Click(object sender, RoutedEventArgs e)
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
if(this.listBox.Items.Count % 2 == 0)
{
bitmapImage.UriSource = new Uri("IMAGE/sample1.png", UriKind.Relative);
}
else
{
bitmapImage.UriSource = new Uri("IMAGE/sample2.png", UriKind.Relative);
}
bitmapImage.EndInit();
this.listBox.Items.Add(bitmapImage);
}
#endregion
#region 항목 삭제 이미지 마우스 DOWN 처리하기 - deleteItemImage_MouseDown(sender, e)
/// <summary>
/// 항목 삭제 이미지 마우스 DOWN 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void deleteItemImage_MouseDown(object sender, MouseButtonEventArgs e)
{
Image deleteItemImage = e.OriginalSource as Image;
ListBoxItem listBoxItem = FindParent<ListBoxItem>(deleteItemImage);
int index = this.listBox.ItemContainerGenerator.IndexFromContainer(listBoxItem);
BitmapImage bitmapImage = listBoxItem.Content as BitmapImage;
this.listBox.Items.RemoveAt(index);
this.listBox.Items.Refresh();
e.Handled = true;
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 부모 찾기 - FindParent<T>(dependencyObject)
/// <summary>
/// 부모 찾기
/// </summary>
/// <typeparam name="T">타입</typeparam>
/// <param name="dependencyObject">의존 객체</param>
/// <returns>부모 객체</returns>
private T FindParent<T>(DependencyObject dependencyObject) where T : class
{
T result = null;
DependencyObject parentDependencyObject = VisualTreeHelper.GetParent(dependencyObject);
if(parentDependencyObject is T)
{
result = parentDependencyObject as T;
}
else if(parentDependencyObject != null)
{
result = FindParent<T>(parentDependencyObject);
}
return result;
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] Vector 구조체 : 각도에서 벡터 구하기 (0) | 2021.08.20 |
---|---|
[C#/WPF] Window 클래스 : 커스텀 윈도우 사용하기 (0) | 2021.08.20 |
[C#/WPF] Application 클래스 : Restart 메소드를 사용해 애플리케이션 재시작하기 (0) | 2021.08.19 |
[C#/WPF] Vector 구조체 : 벡터 각도 구하기 (0) | 2021.08.19 |
[C#/WPF] ResourceDictionary 클래스 : MergedDictionaries 속성을 사용해 Application 객체의 리소스 사용하기 (0) | 2021.07.08 |
[C#/WPF] HwndSource 클래스 : FromHwnd 정적 메소드를 사용해 윈도우 핸들로 윈도우 구하기 (0) | 2021.06.07 |
[C#/WPF] 잠금 화면 설정하기 (기능 개선) (0) | 2021.05.31 |
[C#/WPF] 비동기 가상화 컬렉션 사용하기 (0) | 2021.05.21 |
[C#/WPF] PathGeometry 클래스 : GraphicsPath 객체에서 패스 지오메트리 구하기 (0) | 2021.05.13 |
[C#/WPF] 누겟 설치 : AvalonEdit (0) | 2021.05.10 |
댓글을 달아 주세요