Laden...

Template aus Basisstyle wiederverwenden

Erstellt von mortifiedpenguin vor 2 Jahren Letzter Beitrag vor 2 Jahren 351 Views
M
mortifiedpenguin Themenstarter:in
2 Beiträge seit 2021
vor 2 Jahren
Template aus Basisstyle wiederverwenden

Hallo zusammen!

Ich habe einen Style für ein Window erstellt, so weit, so gut:


<Style x:Key="windowStyle" 
       TargetType="{x:Type Window}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">
                <Border Width="300" Height="300" BorderBrush="Red" BorderThickness="3">
                    <ContentPresenter />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Nun will ich ein spezialisiertes Window für bestimmte Anwendungszwecke, dazu vererbe ich von Window mit einem neuen DependencyProperty und erstelle dazu einen neuen Style. Im Prinzip will ich die Struktur vom Template im Base-Style behalten, und nur den ContentPresenter mit einem Grid füllen, welcher wiederum dann in einer Zelle den Window-Content zeigt:


    <Style x:Key="customWindowStyle" 
           BasedOn="{StaticResource windowStyle}" 
           TargetType="{x:Type local:CustomWindow}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:CustomWindow}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>

                        <Image Grid.Column="0" Source="{TemplateBinding Source}" />
                        <ContentPresenter Grid.Column="1" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Dieser Style überschreibt allerdings natürlich komplett das ControlTemplate von Window, d.h. ich müsste das Template aus dem Basisstyle nochmal komplett kopieren.

Gibt es eine elegante Lösung dafür?

Ich könnte natürlich den ContentPresenter-Teil in ein DataTemplate auslagern, dann wäre ich aber für meinen customWindowStyle an ein bestimmtes ViewModel gebunden. Ich wollte eigentlich eine separate Window-Klasse mit eigenen Dependency-Properties.

Danke!

5.658 Beiträge seit 2006
vor 2 Jahren

Leider nicht. Wenn du das ControlTemplate eines Elements überschreiben willst, mußt du es komplett ersetzen.

Weeks of programming can save you hours of planning

M
mortifiedpenguin Themenstarter:in
2 Beiträge seit 2021
vor 2 Jahren

Danke schonmal für die Antwort. Was ist denn normalerweise die Lösung für dieses Problem? Gehe ich das vielleicht komplett falsch an?

In dem gennanten Beispiel konnte ich die Duplizierung über ein ControlTemplate für ContentControl eliminieren. Was aber natürlich bedeutet, dass ich dort nicht an die Dependency-Properties des Windows binden kann 🙁


    <ControlTemplate TargetType="{x:Type ContentControl}" x:Key="windowContentTemplate">
        <Border BorderBrush="Red" BorderThickness="3">
            <ContentPresenter />
        </Border>
    </ControlTemplate>
    
    <Style x:Key="windowStyle" 
           TargetType="{x:Type Window}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <ContentControl Template="{StaticResource windowContentTemplate}">
                        <ContentPresenter />
                    </ContentControl>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <Style x:Key="customWindowStyle" 
           BasedOn="{StaticResource windowStyle}" 
           TargetType="{x:Type local:CustomWindow}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:CustomWindow}">
                    <ContentControl Template="{StaticResource windowContentTemplate}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="200" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <Image Grid.Column="0" Source="{TemplateBinding Source}" />
                            <ContentPresenter Grid.Column="1" />
                        </Grid>
                    </ContentControl>
                </ControlTemplate>

            </Setter.Value>
        </Setter>
    </Style>

2.079 Beiträge seit 2012
vor 2 Jahren

Lies dich mal in die TemplateParts, damit kannst Du aus dem Code heraus einen Teil des Templates erreichen.
Ob das die bessere Option ist, sei mal dahin gestellt, aber es ist eine Option.
Im Zweifel würde ich mich aber auch für deine Lösung entscheiden, die ist offensichtlicher 🙂

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

F
10.010 Beiträge seit 2004
vor 2 Jahren

Und wenn du es nur für ein einzelnes Window benötigst, mach es da in den Window.Resources und nicht in einer globalen xaml resource