Resource 에서 Style 상속

사내 WPF 프로그램에 어떤 테마가 적용된 것 같습니다.

Button의 경우에는 Grid 바로 밑에 들어있는 형태로 Grid-Button 형태에 대해서만 스타일이 적용되도록 한 것 같습니다. Grid 안에 Button이 들어있더라도, 예를 들어, Grid-StackPanel-Button 순서로 들어있으면 스타일 적용이 안됩니다.

아래와 같은 경우에만 적용이 됩니다.

[되는 경우]

<Grid Grid.Row="1" Grid.ColumnSpan="3">
    <Button x:Name="btnAddCostume" Content="코스튬 추가" />
    <Button x:Name="btnDelCostume" Content="코스튬 삭제" />
</Grid>

[안되는 경우]

<Grid Grid.Row="1" Grid.ColumnSpan="3">
    <StackPanel Orientation="Horizontal">
        <Button x:Name="btnAddCostume" Content="코스튬 추가" />
        <Button x:Name="btnDelCostume" Content="코스튬 삭제" />
    </StackPanel>
</Grid>

이 상황에서 Grid 안에 Button들이 여러 개가 있는데, 이 버튼들이 모두 다닥 다닥 붙어 있습니다.
Margin을 주면 간단하게 해결되는 문제이기 때문에 Button들마다 Margin을 주지 않고, Grid안에 Grid.Resource에서 Target Type 없이 Style을 정의하니까 테마가 풀려버립니다.

[테마가 풀리는 경우]

<Grid Grid.Row="1" Grid.ColumnSpan="3">
    <Grid.Resources>
        <Style TargetType="Button">
            <Setter Property="Margin" Value="0,0,5,0" />
            <Setter Property="Height" Value="28" />
            <Setter Property="Width" Value="110" />
        </Style>
    </Grid.Resources>
    <Button x:Name="btnAddCostume" Content="코스튬 추가" />
    <Button x:Name="btnDelCostume" Content="코스튬 삭제" />
</Grid>

[테마가 풀리지 않는 경우]

<Grid Grid.Row="1" Grid.ColumnSpan="3">
    <Button x:Name="btnAddCostume"
            Width="110"
            Height="28"
            Margin="0,0,5,0"
            Content="코스튬 추가" />
    <Button x:Name="btnDelCostume"
            Width="110"
            Height="28"
            Margin="0,0,5,0"
            Content="코스튬 삭제" />
</Grid>

테마를 통해 Style이 적용되던 게 제가 Resource로 덮어 씌워서 테마가 지워진 느낌입니다.
제가 만든 리소스 스타일에 기존의 테마를 상속받으면 되는데 이런 경우 어떻게 해야할까요?

3개의 좋아요

음. 제생각엔 말씀하신 것처럼 테마 상속 받아서 사용하는게 최선일 것 같습니다 ~

3개의 좋아요

그 테마가 어떤 건지 제가 찾을 수가 없습니다… 방법을 모르는 거 같습니다.

혹시 어떻게 찾아야할까요?

2개의 좋아요

여러 아이디어가 있지만 테스트한 자료 공유합니다.

TestStyleLive3

말씀하신 대로 테스트한 결과 → <Grid.Resources>사용 시 기존에 적용된 Button Style이 반영되지 않습니다.
(버튼의 테마에 관련된 내용이 적용되 지 않는 것으로 보입니다.)

TestStyleLive4

(위 영상을 보시면 default로 설정된 버튼 Style이 적용 됩니다.)
우회 방법으로 ContentControl를 사용했습니다.
ContentControl의 안에서는 Button의 기존 Style을 잘 받아옵니다.
여기에 Margin만 따로 추가하면 될것 같습니다.

출처 → Stack Overflow
참조 문서 → ContentControl Class

2개의 좋아요

@Stupid 님 시간 들여 테스트해주셔서 감사드립니다.
다른 곳에서 @aroooong 님께서 제시해주신 방법으로 해결했습니다.

우선 Based On이 Style말고 Control Type도 지정 가능한 부분이라는 것을 처음 알게 되었습니다.

Style.BasedOn Property (System.Windows) | Microsoft Docs

image

이렇게 하니 기본 버튼에 적용된 스타일을 그대로 불러와서 제가 추가한 부분만 수정이 가능했습니다.

무엇보다, 기존에 Grid-Button 구조일 때만 테마가 적용되었었는데 아래 그림처럼 StackPanel-Button 구조일 때도 기본 버튼의 테마를 상속받아서 그런지 아래 그림과 같이 XAML을 적용해도 테마가 적용되었습니다.

image

@Stupid @aroooong 감사합니다.

8개의 좋아요

좋은 정보 감사합니다. :+1:
테마에서 x:key ="Test"이렇게 key를 일일이 지정해서 가져왔는데, 이렇게 간단하게 할 수 있네요.
적용해보겠습니다.


적용해보았지만 오류가 나서… key를 지정하는 방식으로 가야 겠습니다.

Set1

x:key를 이용해 지정한 Style


문제 2
.
문제1
Control 상속 했을 때 (BasedOn="{StaticResource {x:Type TextBox}}")

문제 1 → TextBox Width 사이즈가 다릅니다…
문제 2 → 디자이너 화면(MainWindow.xaml)에서 VS가 먹통입니다.

원인 분석 → 따로 지정한 TextBox-Style이 2개 있습니다.

// 참조 1
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Width" Value="100" />

// 참조 2
<Style x:Key="Test" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}" >

참조 1에선 Theme에서 상속을 받습니다.
참조 2에선 참조 1에서 상속을 받습니다.–> Width를 받아옵니다. (문제 1의 원인)
문제 2 → 명시되지 않은 TextBox를 상속, 상속을 받음으로 생기는 현상 인것 같습니다.
(따로 지정한 TextBox-Style이 2개 있습니다.) 참조 1 또는 참조 2만 사용 했을 때에는 문제 없이 VS가 돌아갑니다.


(해결법) → (Theme TextBox Style을 상속, x:key를 설정하고 뿌려줍니다)

<Style x:Key="ThemesTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}" />
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource ThemesTextBox}">
<Style x:Key="Test123" TargetType="{x:Type TextBox}" BasedOn="{StaticResource ThemesTextBox}" >

Theme 수정없이 상속 받는 법을 찾고 있었는데, 해결법을 찾았습니다.
감사합니다. :+1:

3개의 좋아요

기본 스타일 상속 관련해서 비슷한 글도 여기 있습니다. :smile:

1개의 좋아요