Dela via


Så här skapar du ett format för en kontroll

Med Windows Presentation Foundation (WPF) kan du anpassa en befintlig kontrolls utseende med din egen återanvändbara stil. Formatmallar kan tillämpas globalt på din app, dina fönster och sidor eller direkt på kontroller.

Skapa ett format

Du kan se det som ett Style praktiskt sätt att tillämpa en uppsättning egenskapsvärden på ett eller flera element. Du kan använda ett format på alla element som härleds från FrameworkElement eller FrameworkContentElement, till exempel en Window eller en Button.

Det vanligaste sättet att deklarera ett format är som en resurs i avsnittet Resources i en XAML-fil. Eftersom formatmallar är resurser följer de samma omfångsregler som gäller för alla resurser. Enkelt uttryckt, där du deklarerar ett format påverkar var formatet kan tillämpas. Om du till exempel deklarerar formatet i rotelementet i din appdefinitions XAML-fil kan formatet användas var som helst i din app.

<Application x:Class="IntroToStylingAndTemplating.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:IntroToStylingAndTemplating"
             StartupUri="WindowExplicitStyle.xaml">
    <Application.Resources>
        <ResourceDictionary>
            
            <Style x:Key="Header1" TargetType="TextBlock">
                <Setter Property="FontSize" Value="15" />
                <Setter Property="FontWeight" Value="ExtraBold" />
            </Style>
            
        </ResourceDictionary>
    </Application.Resources>
</Application>

Om du deklarerar formatet i en av appens XAML-filer kan formatet endast användas i XAML-filen. Mer information om omfångsregler för resurser finns i Översikt över XAML-resurser.

<Window x:Class="IntroToStylingAndTemplating.WindowSingleResource"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:IntroToStylingAndTemplating"
        mc:Ignorable="d"
        Title="WindowSingleResource" Height="450" Width="800">
    <Window.Resources>
        
        <Style x:Key="Header1" TargetType="TextBlock">
            <Setter Property="FontSize" Value="15" />
            <Setter Property="FontWeight" Value="ExtraBold" />
        </Style>
        
    </Window.Resources>
    <Grid />
</Window>

Ett format består av <Setter> underordnade element som anger egenskaper för de element som formatet tillämpas på. I exemplet ovan ser du att formatmallen är inställd på att gälla för TextBlock typer via attributet TargetType . Stilen kommer att ställa in FontSize till 15 och FontWeight till ExtraBold. Lägg till en <Setter> för varje egenskap som stilen ändrar.

Tillämpa en stil indirekt

A Style är ett praktiskt sätt att tillämpa en uppsättning egenskapsvärden på fler än ett element. Tänk till exempel på följande TextBlock element och deras standardutseende i ett fönster.

<StackPanel>
    <TextBlock>My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Exempelskärmbild av styling före

Du kan ändra standardutseendet genom att ange egenskaper, till exempel FontSize och FontFamily, på varje TextBlock element direkt. Men om du vill att dina TextBlock element ska dela vissa egenskaper kan du skapa en Style i avsnittet i Resources XAML-filen, som du ser här.

<Window.Resources>
    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

När du ställer in typen för formatmallen TargetType till TextBlock och utelämnar attributet x:Key, tillämpas formatet på alla TextBlock element som är begränsade till formatet, vilken vanligtvis avser själva XAML-filen.

Nu visas elementen TextBlock på följande sätt.

Formatmall för exempel på skärmbild av basformat

Använd en stil tydligt

Om du lägger till ett x:Key-attribut med ett värde i formatet, tillämpas formatet inte längre implicit på alla element av TargetType. Endast element som uttryckligen refererar till formatet får formatet tillämpat på dem.

Här är formatet från föregående avsnitt, men deklarerat med attributet x:Key .

<Window.Resources>
    <Style x:Key="TitleText" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

För att använda stilen, ange egenskapen på elementet Style till värdet x:Key med ett StaticResource markup-tillägg, som du ser här.

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Observera att det första TextBlock elementet har formatet tillämpat på det medan det andra TextBlock-elementet förblir oförändrat. Det implicita formatet från föregående avsnitt ändrades till ett format som deklarerade x:Key attributet, vilket innebär att det enda element som påverkas av formatet är det som refererade till formatet direkt.

Textblock för exempel på styling-skärmbild

När ett format används, explicit eller implicit, blir det förseglat och kan inte ändras. Om du vill ändra ett format som har tillämpats skapar du ett nytt format för att ersätta det befintliga. För mer information, se egenskapen IsSealed.

Du kan skapa ett objekt som väljer ett format som ska tillämpas baserat på anpassad logik. Ett exempel finns i exemplet för StyleSelector klassen.

Tillämpa ett format programmatiskt

Om du vill tilldela ett namngivet format till ett element programmatiskt hämtar du formatmallen från resurssamlingen och tilldelar den till elementets Style egenskap. Objekten i en resurssamling är av typen Object. Därför måste du omvandla den hämtade formatmallen System.Windows.Style till en Style innan du tilldelar den till egenskapen. Följande kod anger till exempel formatet för ett TextBlock namngivet textblock1 till det definierade formatet TitleText.

textblock1.Style = (Style)Resources["TitleText"];
textblock1.Style = CType(Resources("TitleText"), Windows.Style)

Utöka ett format

Du kanske vill att dina två TextBlock element ska dela vissa egenskapsvärden, till exempel FontFamily och den centrerade HorizontalAlignment. Men du vill också att texten Mina bilder ska ha ytterligare egenskaper. Du kan göra det genom att skapa ett nytt format som baseras på det första formatet, som du ser här.

<Window.Resources>
    <!-- .... other resources .... -->

    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
    
    <!--A Style that extends the previous TextBlock Style with an x:Key of TitleText-->
    <Style BasedOn="{StaticResource {x:Type TextBlock}}"
           TargetType="TextBlock"
           x:Key="TitleText">
        <Setter Property="FontSize" Value="26"/>
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.0" Color="#90DDDD" />
                        <GradientStop Offset="1.0" Color="#5BFFFF" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

Använd sedan formatmallen på en TextBlock.

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Det här TextBlock formatet är nu centrerat, använder ett Comic Sans MS teckensnitt med storleken 26, och förgrundsfärgen inställd på den LinearGradientBrush som visas i exemplet. Observera att det åsidosätter FontSize värdet för basformatet. Om det finns fler än en som Setter pekar på samma egenskap i en Stylehar den Setter som deklareras senast företräde.

Följande visar hur elementen TextBlock nu ser ut:

Formaterade textblock

Det här TitleText formatet utökar formatmallen som har skapats för typen TextBlock , som refereras till med BasedOn="{StaticResource {x:Type TextBlock}}". Du kan också utöka ett format som har ett x:Key med hjälp x:Key av formatet. Om det till exempel finns ett format med namnet Header1 och du vill utöka formatet använder BasedOn="{StaticResource Header1}"du .

Relation mellan egenskapen TargetType och x:Key-attributet

Som tidigare visats gör inställningen TargetType av egenskapen till utan att TextBlock tilldela formatmallen ett x:Key att formatmallen tillämpas på alla TextBlock element. I det här fallet x:Key är implicit inställt på {x:Type TextBlock}. Det innebär att om du uttryckligen anger x:Key värdet till något annat än {x:Type TextBlock}, så tillämpas Style inte automatiskt på alla TextBlock element. I stället måste du använda formatet (genom att använda x:Key värdet) explicit för TextBlock-elementen. Om formatmallen finns i resursavsnittet och du inte anger egenskapen för formatmallen TargetType måste du ange attributet x:Key .

Förutom att ange ett standardvärde för x:KeyTargetType anger egenskapen den typ som setter-egenskaperna gäller för. Om du inte anger en TargetTypemåste du kvalificera egenskaperna i dina Setter objekt med ett klassnamn med hjälp av syntaxen Property="ClassName.Property". I stället för att ställa in Property="FontSize"måste du till exempel ange Property till "TextBlock.FontSize" eller "Control.FontSize".

Observera också att många WPF-kontroller består av en kombination av andra WPF-kontroller. Om du skapar ett format som gäller för alla kontroller av en typ kan du få oväntade resultat. Om du till exempel skapar ett format som riktar sig mot TextBlock typen i en Windowtillämpas formatet på alla TextBlock kontroller i fönstret, även om TextBlock är en del av en annan kontroll, till exempel en ListBox.

Se även