WPF Button 연구

WPF에서 가장 많이 사용되는 컨트롤 중에 하나인 Button에 관한 연구를 진행합니다.

연구 항목

  1. 버튼(Button) 사례
  2. Button Class
  3. Template
  4. Geometry
  5. Trigger
  6. DataContext
  7. DependencyProperty

목표: (속도는 더디지만) 설명과 소스코드를 상세하게 정리하고 WPF Button 관련 정보들을 잘 검증고 지속적으로 관리해 나가는 것에 목적을 두고 있습니다. :smile:

4개의 좋아요

다양한 프로그램에서의 버튼(Button)

GitHub Repository 생성 버튼

image

닷넷데브 토픽 만들기 버튼

image

카카오톡 채팅창 전송 버튼

image

리그오브레전드 안내 가이드 버튼

image

Button Class (버튼 클래스)

이름 UI 타입 네임스페이스 어셈블리
Button ContentControl System.Windows.Controls PresentationFramework.dll

WPF 버튼은 Content 속성을 포함하는 ContentControl 기반의 클래스입니다. ContentControl을 기반으로 하는 클래스는 Button 말고도 Window, UserControl, CheckBox, ToggleButton, Expander 등이 있습니다.

Button 클래스의 가장 큰 특징은 ContentTemplate을 편집할 수 있다는 점과 Click 이벤트를 포함한 Button 동작에 관련된 Event를 사용할 수 있다는 점입니다. 또한 다른 UI 클래스들과 달리 Command라는 ICommand 타입의 속성(DependencyProperty)를 통해 Click 이벤트를 Binding을 통해 연결할 수도 있습니다. 이는 Button 내부적으로 버튼 클릭 시 Command를 ?.Invoke() 하도록 설계되어 있기 때문입니다.

기본 스타일 형태

<Style TargetType="{x:Type Button}">
    <Setter>
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border>
                   <!-- TBD... -->
                    <ContentPresenter/>
                </Border>
            </ControlTemplate>
       </Setter.Value>
   </Setter>
</Style>

Button과 거의(99%) 동일한 DNA
ContentControl을 기반으로 한 모든 컨트롤이 대상입니다.

  • ToggleButton
  • CheckBox
  • RadioButton
  • Window
  • UserControl

TBD…

2개의 좋아요

버튼 Template 예제

  • 깃허브 버튼
  • 닷넷데브 버튼
  • 카카오톡 버튼
  • 리그오브레전드 버튼

다운로드
:point_right: GitHub 소스코드

깃허브 버튼

기본 상태 (Default)

image

색상 표 (HEX)

image BorderBrush #2B9148
image Background #2EA44F
image Foreground #FFFFFF
image Fill #FFFFFF

image Background.IsMouseOver #2c974b

아이콘 (Geometry)

<Geometry x:key="ICON">M8,8V6H10V8H8M7,2H17A2,2 0 0,1 19,4V19A2,2 0 0,1 17,21V22H15V21H9V22H7V21A2,2 0 0,1 5,19V4A2,2 0 0,1 7,2M7,4V9H17V4H7M8,12V15H10V12H8Z</Geometry>

스타일 (ControlTemplate)

<!-- Geometry Path Icon (.SVG) -->
<Geometry x:Key="ICON">M8,8V6H10V8H...</Geometry>

<!-- GitHub Button Style -->
<Style TargetType="{x:Type local:GitHubButton}">
	<Setter Property="UseLayoutRounding" Value="True"/>
	<Setter Property="SnapsToDevicePixels" Value="True"/>
	<Setter Property="Foreground" Value="#FFFFFF"/>
	<Setter Property="FontWeight" Value="Bold"/>
	<Setter Property="Margin" Value="5"/>
	<Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:GitHubButton}">
				<ControlTemplate.Resources>
					<Style TargetType="{x:Type Border}" x:Key="IN.BORDER">
						<Setter Property="BorderBrush" Value="#2B9148"/>
						<Setter Property="BorderThickness" Value="1 1 1 1"/>
						<Setter Property="Background" Value="#2B9148"/>
						<Setter Property="CornerRadius" Value="5"/>
					</Style>
					<Style TargetType="{x:Type StackPanel}" x:Key="IN.PANEL">
						<Setter Property="VerticalAlignment" Value="Center"/>
						<Setter Property="Orientation" Value="Horizontal"/>
					</Style>
					<Style TargetType="{x:Type Viewbox}" x:Key="IN.VBOX">
						<Setter Property="VerticalAlignment" Value="Center"/>
						<Setter Property="Margin" Value="12 0 4 0"/>
						<Setter Property="Width" Value="16"/>
						<Setter Property="Height" Value="16"/>
					</Style>
					<Style TargetType="{x:Type Path}" x:Key="IN.PATH">
						<Setter Property="Data" Value="{StaticResource ICON}"/>
						<Setter Property="Width" Value="24"/>
						<Setter Property="Height" Value="24"/>
						<Setter Property="Fill" Value="#FFFFFF"/>
					</Style>
					<Style TargetType="{x:Type ContentPresenter}" x:Key="IN">
						<Setter Property="VerticalAlignment" Value="Center"/>
						<Setter Property="Margin" Value="0 6 12 6"/>
					</Style>
				</ControlTemplate.Resources>
                <Border Style="{StaticResource IN.BORDER}">
					<StackPanel Style="{StaticResource IN.PANEL}">
						<Viewbox Style="{StaticResource IN.VBOX}">
							<Path Style="{StaticResource IN.PATH}"/>
						</Viewbox>
						<ContentPresenter Style="{StaticResource IN}"/>
					</StackPanel>
				</Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

ControlTemplate 영역 하위 컨트롤 스타일

x:Key TargetType Remark
IN.BORDER Border CornerRadius=“5 5 5 5”
IN.PANEL StackPanel Orientation=“Horizontal”
IN.VBOX ViewBox W16 x H16
IN.PATH Path W24 x H24 (실제 .svg size)
IN ContentPresenter ContentSource=“Content”

WPF 실행 결과
TBD…

image

:point_right: GitHub 소스코드

TBD…

2개의 좋아요