template style plantillas modern gratis for control c# wpf controltemplate

c# - style - Reemplazar parte de la plantilla por defecto en WPF



wpf templates (3)

Desafortunadamente, creo que tienes que reemplazar toda la plantilla:

De MSDN: http://msdn.microsoft.com/en-us/library/aa970773.aspx

Los controles en Windows Presentation Foundation (WPF) tienen una plantilla ControlTemplate que contiene el árbol visual de ese control. Puede cambiar la estructura y la apariencia de un control modificando la Plantilla de control de ese control. No hay manera de reemplazar solo parte del árbol visual de un control; para cambiar el árbol visual de un control, debe establecer la propiedad Plantilla del control en su nueva y completa plantilla de control.

¿Existe alguna forma de "mejor práctica" para reemplazar una parte de la plantilla predeterminada? El caso de uso actual es una vista de árbol. De forma predeterminada, la vista de árbol tiene estas formas de triángulos pequeños para expandir y contraer.

Sé cómo reemplazarlos si reemplazo toda la plantilla de control, como se muestra en el código a continuación. No estoy seguro de si hay una manera de "mantener todos los valores predeterminados, simplemente cambiar XY". No es un estilo, básicamente necesito reemplazar una parte de una plantilla de control existente.

Para ilustrar, eche un vistazo a la siguiente XAML. El primer bloque más pequeño es el XAML relevante que quiero poder adaptar.

La segunda y tercera parte más grandes son básicamente una copia de las plantillas predeterminadas, solo para administrar la parte "modificada" desde el principio.

¿Hay una mejor manera de hacerlo, salvando el largo y confuso XAML en la segunda mitad?

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton"> <Setter Property="Focusable" Value="False"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ToggleButton"> <Grid Width="15" Height="13" Background="Transparent"> <Path x:Name="ExpandPath" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,1,1,1" Fill="Black" Data="M 4 0 L 8 4 L 4 8 Z"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter Property="Data" TargetName="ExpandPath" Value="M 0 4 L 8 4 L 4 8 Z"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>

<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 Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" 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}"> <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> </Border> <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsExpanded" Value="false"> <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/> </Trigger> <Trigger Property="HasItems" Value="false"> <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Width" Value="Auto"/> </MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinWidth" Value="75"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false"/> <Condition Property="Height" Value="Auto"/> </MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinHeight" Value="19"/> </MultiTrigger> <Trigger Property="IsSelected" Value="true"> <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="IsSelectionActive" Value="false"/> </MultiTrigger.Conditions> <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter>


En realidad hay una forma (tipo de). Puede crear su propio control personalizado y anular la función OnApplyTemplate para cambiar el estilo dinámicamente.

Por ejemplo, cree un control personalizado como tal (estoy haciendo esto en Silverlight pero es lo mismo que supongo):

namespace SilverlightClassLibrary1 { public class MyButton: Button { public string BackgroundColor { get; set; } public override void OnApplyTemplate() { base.OnApplyTemplate(); if (BackgroundColor != null) { Rectangle r = this.GetTemplateChild("BackgroundGradient") as Rectangle; if (r != null) { r.Fill = new SolidColorBrush(Color.FromArgb(255, Convert.ToByte(BackgroundColor.Substring(1,2),16), Convert.ToByte(BackgroundColor.Substring(3,2),16), Convert.ToByte(BackgroundColor.Substring(5,2),16))); } } } } }

La parte interesante es el método GetTemplateChild , que está buscando un control Rectangle llamado "BackgroundGradient". (Por cierto, es más fácil si define controles personalizados en un proyecto separado, así que cree un nuevo proyecto de "biblioteca de clases de Silverlight" si aún no lo ha hecho y póngalo en ese proyecto).

Luego agregue un nuevo archivo de diccionario de recursos, anule la plantilla de control y asegúrese de tener un rectángulo llamado "BackgroundGradient". En este caso, estamos usando la plantilla de control de botón estándar que he reducido un poco:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:custom="clr-namespace:SilverlightClassLibrary1;assembly=SilverlightClassLibrary1"> <Style TargetType="custom:MyButton"> <Setter Property="Background" Value="#FF1F3B53"/> <Setter Property="Foreground" Value="#FF000000"/> <Setter Property="Padding" Value="3"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="BorderBrush"> <Setter.Value> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFA3AEB9" Offset="0"/> <GradientStop Color="#FF8399A9" Offset="0.375"/> <GradientStop Color="#FF718597" Offset="0.375"/> <GradientStop Color="#FF617584" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid> <Border x:Name="Background" CornerRadius="3" Background="White" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}"> <Grid Background="{TemplateBinding Background}" Margin="1"> <Border Opacity="0" x:Name="BackgroundAnimation" Background="#FF448DCA" /> <Rectangle x:Name="BackgroundGradient" Fill="White" > </Rectangle> </Grid> </Border> <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}"/> <Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" /> <Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" Margin="1" Stroke="#FF6DBDD1" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>

Así que ahora puede declarar un control de botón y anular un estilo si desea:

<UserControl x:Class="SilverlightApplication1.MainPage" ... xmlns:custom="clr-namespace:SilverlightClassLibrary1;assembly=SilverlightClassLibrary1"> <custom:MyButton>Normal Button 1</custom:MyButton> <custom:MyButton>Normal Button 2</custom:MyButton> <custom:MyButton BackgroundColor="#8888cc">Customized Background</custom:MyButton>

Supongo que podría ser aún más inteligente y pasar a través de un nombre de recurso o un nombre de estilo y cargarlo dinámicamente.

Luego debe incluir su archivo de recursos como parte de su aplicación:

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SilverlightApplication1.App" > <Application.Resources> <ResourceDictionary > <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Dictionary1.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>

y verás los cambios de propiedad personalizados en tu diseñador XAML.