본문 바로가기
프로그래밍 언어/WPF

[C#] WPF - Round Button 생성

by Jinwood 2024. 4. 8.
반응형

WPF 컨트롤 생성에 있어 Round Button 컨트롤을 만드는 작업은 필수적으로 거치는 단계인듯하다. 가장 자주 사용되고 접근하기 쉬운 컨트롤이 Button이고, 요즘 UI들은 각진 버튼을 보기 어렵기 때문이다. Round Button 구현함으로써 Style 생성 및 적용 방법과 컨트롤 구현 방법에 대해 있고, 다른 컨트롤을 생성하기 위한 힌트(아이디어) 얻을 있다.

 

기본적으로 Button에는 CornerRadius 속성이 없다. 따라서 Button Style 적용, ControlTemplate 통해 Button 형태를 재정의한다. 아래 코드는 CornerRadius = 3 Round Button 만든 코드이다. ControlTemplate 내부 코드를 보면 먼저 Border 생성하고, Border 내부에 ContentPresenter 생성하여 버튼과 유사한 형태가 되도록 만들어준다. 그리고 Border CornerRadius 값을 정의함으로써 Round Button 생성한다.

 

Border CornerRadius 속성을 가지고 있기 때문에, 적절한 CornerRadius 값을 입력하면 된다. 버튼의 Background Border Background 사용한다. 글자 색상은 ContentPresenter에서 TextElement.Foreground 값으로 정의한다. ContentPresenter TextElement FontSize, FontFamily, FontStretch, FontStyle, FontWeight, Foreground 속성을 가지며, Background 값은 가지고 있지 않다. Border ContentPresenter x:Name 설정한 이유는 아래에 조금 자세하게 설명하였다.

 

<Grid>
    <Button x:Name="botton_Test" Content="Test Button" 
           Width="200" Height="25" IsEnabled="True">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border x:Name="border" CornerRadius="3" Background="Blue">
                                <ContentPresenter x:Name="contentPresenter"
                                                  HorizontalAlignment="Center"
                                                  VerticalAlignment="Center"
                                                  TextElement.Foreground="White" />
                            </Border> 
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Button.Style>
    </Button>
</Grid>

 

이렇게 Border ContentPresenter 이용한 Round Button을 생성하고나면 의문이 발생한다. 사이트나 Application에서 버튼을 떠올려보면, 마우스가 버튼 위에 올라갔을 때나 버튼을 클릭했을 때에 버튼 색 또는 글자 색이 변경되면서 사용자에게 버튼이 어떤 동작을 수행한다는 인식을 하게끔 알려준다.

 

하지만 조금 생성한 버튼을 동작해보면 클릭했다는 느낌이 없다. 사용자가 마우스를 버튼 위에 올려두었다는, 또는 버튼을 클릭했다는 느낌을 주려면 Trigger 이용하여 특정 이벤트가  발생되었을 Button 속성(Border와 ContentPresenter) 변경해주어야 한다.

 

아래 코드를 보면 조금 생성한 Round Button Trigger 속성을 추가한 것을 확인할 있다. Trigger '어느 특정한 동작에 반응해 자동으로 필요한 동작을 실행하는 것' 을 의미한다. 아래 코드를 바탕으로 이해하자면 입력한 Property 대하여 Value 충족되었을 경우, Setter 표기된 동작을 수행한다는 뜻이다.

 

Trigger 이용하여 버튼이 비활성화(IsEnabled = False) 되었을 경우, 마우스가 버튼 위로 올라갔을 경우(IsMouseOver = True), 버튼을 클릭했을 경우(IsPressed = True) 대한 코드를 작성했다. 3가지 동작에 대해 각각 Trigger 작성했으며, 해당 Trigger 조건이 충족된 경우 Border 또는 ContentPresenter, 혹은 컨트롤 모두에 특정 속성을 변경해주었다.

 

<Grid>
    <Button x:Name="botton_Test" Content="Test Button" 
            Width="200" Height="25" IsEnabled="True">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border x:Name="border" CornerRadius="3" Background="Blue">
                                <ContentPresenter x:Name="contentPresenter"
                                                  HorizontalAlignment="Center"
                                                  VerticalAlignment="Center"
                                                  TextElement.Foreground="White" />
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsEnabled" Value="False">
                                    <Setter Property="Opacity" Value="0.35"/>
                                </Trigger>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter TargetName="border" 
                                            Property="Background" 
                                            Value="CornflowerBlue"/>
                                    <Setter TargetName="contentPresenter" 
                                            Property="TextElement.Foreground" 
                                            Value="Black"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="True">
                                    <Setter TargetName="border"  
                                            Property="Background" 
                                            Value="MediumBlue"/>
                                    <Setter TargetName="contentPresenter" 
                                            Property="TextElement.Foreground" 
                                            Value="White"/>
                                    <Setter TargetName="contentPresenter" 
                                            Property="TextElement.FontWeight" 
                                            Value="Bold"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate> 
                    </Setter.Value> 
                </Setter> 
            </Style>
        </Button.Style>
    </Button>
</Grid>

 

Trigger 내부의 Setter에는 Property Value, TargetName 사용되었다. Property 변경하려는 속성이고, Value 변경하려는 속성값이다. TargetName 특정 컨트롤의 Property 변경하려는 경우 사용되며, TargetName 설정되지 않은 경우 Control 자체(여기서는 Button) 적용된다.

 

제시된 예에서 Trigger 하나의 조건에 대해서면 동작을 수행한다. 조금 복잡하고 다양한 컨트롤의 집합으로 컨트롤이 존재한다면, 하나의 조건으로만 특정 동작을 수행하기에는 답답할 있다. 여러 조건이 충족될 특정 동작을 수행하도록 만들려면 MultiTrigger 사용하면 된다.

 

MultiTrigger 이후에 따로 작성할 예정.

 

끝!

반응형

댓글