Reputation: 14912
It seems very hard to achieve something rather trivial in WPF...
I need to design a toggle button with a specific look (and feel). I made a small project to demonstrate the problem.
"ToggleButton user control" :
<UserControl x:Class="WpfApp4.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"
Name="Bla">
<UserControl.Resources>
<Style TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Ellipse Width="300" Height="300" Fill="Yellow"/>
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<ToggleButton
Width="300" Height="300">
<ContentControl Content="{Binding ElementName=Bla, Path=MainContent}"/>
</ToggleButton>
</UserControl>
Dependency property:
public static DependencyProperty MainContentProperty = DependencyProperty.Register(
"MainContent",
typeof(object),
typeof(UserControl1),
null);
public object MainContent
{
get => GetValue(MainContentProperty);
set => SetValue(MainContentProperty, value);
}
The way I want to use the control:
<local:UserControl1>
<TextBlock>Whatever</TextBlock>
</local:UserControl1>
When I run the program, the textbox appears "Whatever", but the style is not applied, the ellipse won't show.
What's the correct way of doing this?
=== Update ===
OK, getting somewhere... finally...
Now I got this as user control:
<UserControl x:Class="WpfApp4.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:wpfApp4="clr-namespace:WpfApp4"
mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"
Name="Bla">
<UserControl.Resources>
<Style TargetType="wpfApp4:UserControl1">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ToggleButton>
<Grid>
<Ellipse Width="300" Height="300" Fill="Yellow"/>
<ContentPresenter Content="{Binding ElementName=Bla, Path=MainContent}" />
</Grid>
</ToggleButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<ContentPresenter/>
</UserControl>
And this is how I use it:
<local:UserControl1>
<local:UserControl1.MainContent>
<TextBlock>Whatever</TextBlock>
</local:UserControl1.MainContent>
</local:UserControl1>
That finally gives me a toggle button with the style applied (the ellipse shows up) and the textbox is shown as well.
So, this works. Is this the way you mean it should work? Or can it be simplified?
Upvotes: 0
Views: 2683
Reputation: 2052
It should be more like
<local:UserControl1>
<local:UserControl1.MainContent>
<TextBlock>Whatever</TextBlock>
</local:UserControl1.MainContent>
</local:UserControl1>
But you should look forward overriding ContentControl which would be more adequate rather then using UserControl.
By the way why did you put a ContentControl inside ToggleButton? ToggleButton by itself is a ContentControl it has it's own Content property.
Update:
All depends on what you whant to do. If it is only change the visual of the toggle button, then just create a toggle button style like this:
<ToggleButton>
<TextBlock>Whatever</TextBlock>
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid>
<Ellipse Width="300" Height="300" Fill="Yellow"/>
<ContentPresenter Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>
Ofcorse if you want to use your style across the application it is better to define the style in a resource dictionnary (for exemple in App.xaml), give it a key and call it on each toggle button using {StaticResource key}
.
If on the other hand, you want to add some logic, you have to create a control class inheriting from ToggleButton and add the logic inside.
Upvotes: 2