You could define 2 different Style properties in your custom control and bind them to the Style property of the individual buttons, thus allowing clients to set the style for the two controls independently of each other.
XAML file:
<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>
Code-behind file:
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); }
}
}
}
It is a good idea to implement these 2 properties as dependency properties, since that will make them conform to the other Style properties in standard WPF controls.
Now you can set the style for the buttons like you would in any WPF control:
<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>
Alternatively you could have the 2 buttons share the same Style by exposing a single property in your custom control which you bind to the Style property of both internal controls.
UPDATE
You don't have to define the FirstButtonStyle and SecondButtonStyle properties as dependency properties. The important thing is that the internal bindings to the buttons' Style properties are updated whenever their value changes. You can accomplish this by implementing the INotifyPropertyChanged interface in your user control and raise the OnPropertyChanged event in the property setters.
You could also assign a "default style" to the 2 properties in the user control's constructor. Here is an example:
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));
}
}
}
}