WPF Style Template부분 수정 질문드립니다.

제가 WPF 공부하는 도중 style 을 여러번 만지다가 이제 Template를 자주 수정하게 되서 하나하나 수정해가며 만들던 도중 모든 내용은 다 똑같은데 Template 안에서 일부분만 수정하고 싶은게 생겨서 평소에는 스타일 전체를 복사해서 그 부분만 수정해서 key 이름을 바꿔가며 사용했는데 이러다보니깐 리소스 사전 코드줄이 엄청 길어지더라구요

예를들어

<Style x:Key="MainType" TargetType="{x:Type TreeViewItem}">
    <Setter Property="Foreground" Value="#FFFFFF"/>
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Margin" Value="0,0,0,0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TreeViewItem}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition MinWidth="19" Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition MinHeight="19"/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Rectangle x:Name="HorLn" Margin="6,0,5,0" Height="1" Stroke="#DCDCDC" SnapsToDevicePixels="True"  StrokeDashCap="Square" StrokeDashArray="0,3"/>
                    <Rectangle x:Name="VerLn" Width="1" Stroke="#DCDCDC" Margin="0,7,1,-5" Grid.RowSpan="2" SnapsToDevicePixels="true" Fill="White" StrokeDashCap="Square" StrokeDashArray="0,3"/>
                    <ToggleButton Margin="-1,0,0,0" x:Name="Expander" Style="{StaticResource RectangleToggleButton}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/>
                    <Border Name="Bd" Grid.Column="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
                        <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Border>
                    <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

위의 스타일에서

<ToggleButton Margin="-1,0,0,0" x:Name="Expander" Style="{StaticResource RectangleToggleButton}" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/>

토글 버튼의 style 부분만 바꾸려고 할 시 쉽게 바꾸는 팁 같은게 있을까요?

2개의 좋아요

Style 속성도 DependencyProperty로 바인딩이 가능할 것 같습니다.

바인딩이 가능하다면

미리 다수의 토글 버튼에 대한 style만 따로 정의해 놓고,

어떤 조건에 의해 어떤 style을 적용 할지는 개발자가 알기에

그 조건을 바인딩 컨버터에서 어떤 스타일을 적용할지 처리하면 될 것 같습니다.

예로

<Style x:Key="기본_토글버튼" TargetType="ToggleButton">
</Style>

<Style x:Key="특별한_토글버튼" TargetType="ToggleButton" BasedOn="{StaticResource 기본_토글버튼}">
</Style>

요로케 여러개를 정의하고,

<Style x:Key="MyStyle">
            <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                        <ToggleButton  Style="{Binding 조건, Converter={컨버터처리}" />
                </ControlTemplate>
            </Setter.Value>

[..이하생략..]

컨버터에서

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
     //여기에 조건에 따라 어떤 스타일을 반환할 것인지 처리
    return Application.Current.FindResource("특별한_토글버튼");
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    throw new NotImplementedException();
}
3개의 좋아요

ContentPresenter를 통해 처리하는 방법도 있습니다.

Expand 버튼 위치에 ContentPrsenter를 추가하고,

<ContentPresenter ContentSource="Expander" 
                  ContentTemplate="{TemplateBinding ExpanderTemplate}"/>

이렇게 하면 좀 더 유연하게 부분적으로 관리할 수 있지만, DependencyProperty를 두 개나 더 만들어야 하는 불편함이 생길 수 있습니다. (Expander, ExpanderTemplate)

그리고 TreeView/TreeViewItem 클래스도 새롭게 만들어주어야 하고요.

할 일이 너무 많죠… :sweat_smile: :joy:

2개의 좋아요

아!

저는 트리뷰 컨트롤 Style 한정이 아닌

일반적으로 Style내에서 유동적으로 다른 FrameworkElement의 Style을 설정 하는 방법을 생각해서 답변을 달아 드렸던 것인데,

트리뷰 컨트롤의 노드 축소/확장에 대한 토글버튼에 대한 것이라면

트리뷰 데이터 가시화를 HierarchicalDataTemplate으로 구성하시면

트리의 뎁스(depth) 별로 각 노드의 축소/확장 토글 버튼을 다르게 각각 꾸밀 수 있습니다!

트리뷰 컨트롤에 HierarchicalDataTemplate 으로 데이터를 표현 하는 방법도 찾아 보세요.

3개의 좋아요

다들 감사합니다
결국 스타일을 하나하나 만드는 방법밖에 없나보네요

BasedOn처럼 스타일을 불러와서 수정할 부분만 바꾸는 방식처럼 Template에서도 x:Name같은 설정해서 그 부분만 호출해서 바꾸는 그런 편리한 기능이 있을까 싶었습니다~

2개의 좋아요