Come restyle un controllo nidificato in un controllo personalizzato?
-
06-09-2019 - |
Domanda
Si supponga che si sta sviluppando un controllo personalizzato in WPF che contiene al suo interno alcuni altri controlli di base. Per farla semplice supporre che esso contiene 2 tasti .
Ora si vuole utilizzare questo controllo personalizzato nella vostra applicazione, ma si vuole restyling un po '.
CASE 1
Se, nella definizione del controllo personalizzato, entrambi i pulsanti hanno lo stesso stile (WPF default) e si desidera restyling sia, dovrebbe essere facile:
<mc:MyControl>
<mc:MyControl.Resources>
<Style x:Key={x:Type Button}, TargetType={x:Type Button}>
<!-- Insert the new style here -->
</Style>
</mc:MyControl.Resources>
<mc:MyControl>
CASO 2
Se, nella definizione del controllo personalizzato, entrambi i pulsanti hanno lo stesso stile (impostazione predefinita WPF), ma si desidera li restyling con due stili differenti , qual è il modo migliore per risolverlo?
CASO 3
Se, nella definizione del controllo personalizzato, entrambi i pulsanti hanno lo stesso stile, che fa riferimento a uno stile definito all'interno del controllo personalizzato , e si desidera restyling loro, qual è il modo migliore per risolverlo ?
Grazie in anticipo per tutto l'aiuto
Soluzione
Si potrebbe definire 2 diversi Stile immobili a controllo personalizzato e li legano alla proprietà Style dei singoli pulsanti , permettendo così ai clienti di impostare lo stile per i due controlla indipendentemente l'uno dall'altro.
file XAML:
<UserControl x:Class="MyNamespace.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="MyControl">
<StackPanel>
<Button Name="FirstButton"
Style={Binding ElementName=MyControl, Path=FirstButtonStyle}
Content="First Button" />
<Button Name="SecondButton"
Style={Binding ElementName=MyControl, Path=SecondButtonStyle}
Content="Second Button" />
</StackPanel>
</UserControl>
file code-behind:
using System;
using System.Windows;
using System.Windows.Controls;
namespace MyNamespace
{
[StyleTypedProperty(
Property = "FirstButtonStyle",
StyleTargetType = typeof(Button))]
[StyleTypedProperty(
Property = "SecondButtonStyle",
StyleTargetType = typeof(Button))]
public partial class MyControl : UserControl
{
public static readonly DependencyProperty FirstButtonStyleProperty =
DependencyProperty.Register(
"FirstButtonStyle",
typeof(Style),
typeof(MyControl)
);
public Style FirstButtonStyle
{
get { return (Style)GetValue(FirstButtonStyleProperty); }
set { SetValue(FirstButtonStyleProperty, value); }
}
public static readonly DependencyProperty SecondButtonStyleProperty =
DependencyProperty.Register(
"SecondButtonStyle",
typeof(Style),
typeof(MyControl)
);
public Style SecondButtonStyle
{
get { return (Style)GetValue(SecondButtonStyleProperty); }
set { SetValue(SecondButtonStyleProperty, value); }
}
}
}
E 'una buona idea per attuare questi 2 proprietà come proprietà di dipendenza, dal momento che li renderà conformi alle altre proprietà di stile a controlli standard WPF.
Ora è possibile impostare lo stile per i pulsanti come si farebbe in qualsiasi controllo WPF:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:MyNamespace"
Title="MyControl Sample"
Height="300"
Width="300">
<Window.Resources>
<Style x:Key="GreenButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green" />
</Style>
<Style x:Key="RedButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
</Style>
</Windows.Resources>
<StackPanel>
<local:MyControl FirstButtonStyle="{StaticResource GreenButton}"
SecondButtonStyle="{StaticResource RedButton}" />
</StackPanel>
</Window>
In alternativa si potrebbe avere i 2 tasti condividono lo stesso stile esponendo una unica proprietà nel vostro controllo personalizzato, che si associa alla proprietà Style di entrambi i controlli interni.
Aggiorna
Non è necessario definire le FirstButtonStyle e SecondButtonStyle proprietà come proprietà di dipendenza. La cosa importante è che le associazioni interne ai pulsanti Stile le proprietà vengono aggiornati ogni volta che il loro valore cambia. È possibile ottenere questo risultato l'attuazione del INotifyPropertyChanged interfaccia il controllo utente ed aumentare il OnPropertyChanged evento nei setter di proprietà.
Si potrebbe anche assegnare uno "stile di default" per le 2 immobili a costruttore del controllo dell'utente. Ecco un esempio:
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace MyNamespace
{
[StyleTypedProperty(
Property = "FirstButtonStyle",
StyleTargetType = typeof(Button))]
[StyleTypedProperty(
Property = "SecondButtonStyle",
StyleTargetType = typeof(Button))]
public partial class MyControl : UserControl, INotifyPropertyChanged
{
private Style firstButtonStyle;
private Style secondButtonStyle;
public MyControl()
{
Style defaultStyle = new Style();
// assign property setters to customize the style
this.FirstButtonStyle = defaultStyle;
this.SecondButtonStyle = defaultStyle;
}
public Style FirstButtonStyle
{
get { return firstButtonStyle; }
set
{
firstButtonStyle = value;
OnPropertyChanged("FirstButtonStyle");
}
}
public Style SecondButtonStyle
{
get { return secondButtonStyle; }
set
{
secondButtonStyle = value;
OnPropertyChanged("SecondButtonStyle");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}