How to configure Contentpresenter in nested ControlTemplate? - wpf

I have the following code:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Button>
<Button.Template>
<ControlTemplate>
<DockPanel>
<Image Source="{...}"/>
<ContentPresenter .../>
</DockPanel>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
I need button inside template for binding possibility. The nested template defines the appearance.
The question: <ListBoxItem Content="Start"/> does not work with code above. I need something like root Contentpresenter that refers to Contentpresenter inside button template. How can I do this?
Thanks in advance!

<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Button>
<Button.Template>
<ControlTemplate>
<DockPanel>
<Image Source="{...}"/>
<ContentPresenter Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=Content}"/>
</DockPanel>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>

Related

WPF: How to use BasedOn Style

I am new to WPF and I created the following simple style example. But it doesn't work properly and button's content doesn't show although I can still click on it. Can anyone tell me why it is broken?
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Blue"
BorderThickness="5"
Background="Aqua"
Width="80"
Height="40">
<ContentPresenter></ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Grid" x:Name="GridWithMarginStyle">
<Setter Property="Margin" Value="12"></Setter>
</Style>
</Window.Resources>
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<EventSetter Event="Button.Click" Handler="ButtonHandler" />
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Style>
</StackPanel.Resources>
<Button Name="OkBtn">OK</Button>
<Button Name="CancelBtn" Click="CancelBtn_Click">Cancel</Button>
</StackPanel>
You are using the BasedOn property in the correct way. The problem is that your ContentPresenter is not binded to the control it renders (i.e. the button).
Just try to replace your ControlTemplate XAML with this one:
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Blue"
BorderThickness="5"
Background="Aqua"
Width="80"
Height="40">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
By using TemplateBinding you can bind the ContentPresenter to the Content property of your templated control.

Syling child elements

I have style for Button
<Style x:Key="menu_button" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Label Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
it must be applied to the buttons
<StackPanel>
<Button Content="Создать тест" Style="{DynamicResource menu_button}"/>
<Button Content="Тесты" Style="{DynamicResource menu_button}"/>
</StackPanel>
How to make that do not prescribe style to each button, and enter it in the StackPanel. After all, it will be very tiring
In case you can move the style and you do not use the style at another place you can do it this way:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Label Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<Button Content="Создать тест"/>
<Button Content="Тесты"/>
</StackPanel>

WPF - TemplateBinding doesn't recognize member content

Alright, so I have a window with the following resources
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<TextBlock Text="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
I am getting an error saying that, "The member "Content" is not recognized or is not accessible."
What am I doing wrong?
You will have to define TargetType on ControlTemplate
<ControlTemplate TargetType="Button">
<Grid>
<TextBlock Text="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<TextBlock Text="{TemplateBinding Button.Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
or
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<TextBlock Text="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF Button style with Image

I want to create a style for button with different images inside. I try to do following:
<Style TargetType="Button"
x:Key="PaintButton">
<Setter Property="Width"
Value="40"></Setter>
<Setter Property="Height"
Value="40"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border CornerRadius="3"
BorderThickness="2"
BorderBrush="Green">
<Image Source="{TemplateBinding Button.Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and try to use:
<Button Content="images/pen.png"
HorizontalAlignment="Left"
Style="{DynamicResource PaintButton}" />
but images is not shown. Why and how to do it correctly?
The "Image" is not a correct source for another Image.
Either use BitmapImage as Button's contents or use ContentPresenter in the template.
Option 1.
<Button Style="{StaticResource PaintButton}">
<BitmapImage UriSource="Back_Forward.png"/>
</Button>
Option 2.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border CornerRadius="3"
BorderThickness="2"
BorderBrush="Green">
<ContentPresenter Content="{TemplateBinding Button.Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Please try this
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<StackPanel Orientation="Horizontal">
<Grid Height="30" Width="30" Background="{TemplateBinding Background}"/>
<TextBlock Text="{TemplateBinding Content}" TextAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
<Button Name="btnPrintCard" Margin="2" Content="Print Card">
<Button.Background>
<ImageBrush ImageSource="images/ic_print_black_48dp.png"/>
</Button.Background>
</Button>

WPF ContextMenu Design. How to set Background in WPF MenuItem?

I create popup menu like this.
<DockPanel.ContextMenu>
<ContextMenu Background="#CD252220" Opacity="0.95" Foreground="LightGray" BorderBrush="DarkGray">
<MenuItem Header="_Save Image..." x:Name="btSave" IsEnabled="False" Click="btSave_Click" Style="{StaticResource MyStyle}">
<MenuItem.Icon>
<Image Source="icons/save.png" Width="16" Height="16" Style="{StaticResource IconStyle}"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</DockPanel.ContextMenu>
Why left-side of this menu is WHITE????? It'll be a #CD252220 color or transparent, bun not white!!!!!!
How to fix it? :)
http://itrash.ru/idb/40e872e71346dcf9bd58ba8aec0b2a17/omenu.png.html - menu screenshot
P.S. In XP it's OK. Menu is White only on Vista (don't have W7)
I find solution! You have to just set property OverridesDefaultStyle in Style-defenition section ;)
<Style x:Key="{x:Type ContextMenu}" TargetType="{x:Type ContextMenu}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Border Background="#CD222120" CornerRadius="7, 7, 8, 8" BorderBrush="DarkGray" BorderThickness="2" Opacity="0.96">
<StackPanel ClipToBounds="True" Orientation="Vertical" IsItemsHost="True" Margin="5,4,5,4"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}" TargetType="{x:Type MenuItem}">
<Border Name="Border" >
<Grid>
<ContentPresenter Margin="6,3,6,3" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
If you will declare a custom style for your context menu, This way it will be same for all OS.

Resources