To set padding for textblock inside ContentPresenter - wpf

<ControlTemplate TargetType="TabItem">
<Border x:Name="Border" Margin="{TemplateBinding Margin}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{StaticResource DarkGray}" CornerRadius="5,5,0,0">
<ContentPresenter x:Name="Content" ContentSource="Header"
TextElement.FontSize="14" TextBlock.TextAlignment="Center"
HorizontalAlignment="Center" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center">
</ContentPresenter>
</Border>
in the above code there will be a default textblock inside ContentPresenter tag. I need to set padding for that Textblock.
TextBlock.Padding="8"
will not work. How to set padding for that TextBlock.

Related

DisplayMemberPath not working for ListBox with custom ListBoxItem control

I've configured ListBox to use custom ControlTemplate for it self and custom ControlTemplate for ListBoxItem. Unfortunately such change disables the default behvaiour of DisplayMemberPath property.
// resource dictionary of ListBox control template
<ControlTemplate x:Key="CustomListBox" TargetType="ListBox" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib">
<Border CornerRadius="3" BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="1,1,1,1" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="Bd" SnapsToDevicePixels="True">
<ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
//trigger code omitted
<Style TargetType="ListBox">
<Setter Property="Control.Template" Value="{StaticResource CustomListBox}"></Setter>
</Style>
// resource dictionary of ListBoxItem control template
<ControlTemplate x:Key="CustomListBoxItem" TargetType="ListBoxItem" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Border BorderThickness="0" CornerRadius="3" Padding="6 6" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="White" Name="Bd" SnapsToDevicePixels="True">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
<Label Height="3"></Label>
</StackPanel>
</ControlTemplate>
// trigger code omitted
<Style TargetType="ListBoxItem">
<Setter Property="Control.Template" Value="{StaticResource CustomListBoxItem}"></Setter>
<Setter Property="ItemsControl.DisplayMemberPath" Value="MatchText"></Setter>
</Style>
XAML
<ListBox x:Name="listBox" DisplayMemberPath="MyCustomText">
The DataContext of listBox is set using code. If I omit setting CustomListBoxItem as the control template, than it works as expected. How do you enable DisplayMemberPath when using custom control templates for ListBox and ListBoxItem?

How to create a button with a smaller hit area than its visual area?

I'm trying to create buttons with smaller hit area to prevent misoperation in an industrial touchscreen PC program. Here is a sample,
and only the white area should response to touch and mouse operations.
I've tried to use ControlTemplate
<ControlTemplate x:Key="ButtonToTouch" TargetType="{x:Type Button}">
<Grid>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
<Button Background="{x:Null}" BorderBrush="{x:Null}" FontSize="{TemplateBinding FontSize}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Button.Content>
<Grid Margin="8" >
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Rectangle Fill="Transparent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</Grid>
</Button.Content>
</Button>
</Grid>
</ControlTemplate>
Now mouse enter event works that way, but it seems that every visible pixel in the button template can trigger the click event, so i have to set the background of the border to null, and set the background somewhere out of the template.
Any suggestions? Thanks for any help.
set IsHitTestVisible="False" on Border. With 8 Margin on Grid, 8px wide area will not register input.
<ControlTemplate x:Key="ButtonToTouch" TargetType="{x:Type Button}">
<Grid>
<Border BorderBrush="{TemplateBinding BorderBrush}"
IsHitTestVisible="False"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"/>
<Grid Margin="8">
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Rectangle Fill="Transparent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</Grid>
</Grid>
</ControlTemplate>

WPF ViewBox as Content in style, working only on last element that use this style

I have custom control with custom property VectorImage.
This is the style where is used ViewBox with VectorImage as content of Label:
<Style x:Key="Button-SidePanel" TargetType="c:CustomButton">
<Setter Property="VectorImage" Value="{StaticResource VectoroImage_1}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:CustomButton}">
<Border x:Name="border" SnapsToDevicePixels="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" Grid.Row="0" x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
<Label x:Name="ButtonImage" Grid.Column="1" Grid.Row="0" Width="30" Height="30" Margin="0,0,10,0" Content="{TemplateBinding VectorImage}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here I have buttons that use this Style:
<c:CustomButton x:Name="Button_1" Content="Bt1" Style="{StaticResource Button-SidePanel}" />
<c:CustomButton x:Name="Button_2" Content="Bt2" Style="{StaticResource Button-SidePanel}" />
<c:CustomButton x:Name="Button_3" Content="Bt3" Style="{StaticResource Button-SidePanel}" />
<c:CustomButton x:Name="Button_4" Content="Bt4" Style="{StaticResource Button-SidePanel}" />
But only last item Button_4 shows the Label content (viewbox with vector image).
And if I remove Button_4, then Button_3 shows the Label content.
SOLUTION:
Using DataTemplate and them set ContentTemplate
Answer from:
Style within DataTemplate is only being applied to the last item in ItemsControl?

WPF: ItemsControl's border not visible

I followed the instruction in this blog to add ScrollIntoView to ItemsControl.
But this makes the border invisible:
<ItemsControl BorderBrush="Black"
BorderThickness="3">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<TextBlock Text="Test" />
<TextBlock Text="Test" />
<TextBlock Text="Test" />
</ItemsControl>
In order to display the border, I have to remove:
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
But this way I won't be able to use the ScrollIntoView method.
Any ideas? Thanks
You need to include the border in the template.
<ControlTemplate>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>

How can I reference an element inside a control template

Say I wanna put a CheckBox inside a Button. Is there anyway for me to reference that checkbox in code? i.e. In Window1.cs I want to write something like: testButton.innerCheckBox.DoStuff();
<ControlTemplate TargetType="{x:Type Button}">
<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}" RenderDefaulted="{TemplateBinding IsDefaulted}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" ThemeColor="NormalColor">
<Grid Width="32.083" Height="13.277">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="Stretch" Margin="{TemplateBinding Padding}" VerticalAlignment="Stretch" RecognizesAccessKey="True" d:LayoutOverrides="Width, Height"/>
<CheckBox x:Name="innerCheckBox" HorizontalAlignment="Left" VerticalAlignment="Top" Content="CheckBox"/>
</Grid>
</Microsoft_Windows_Themes:ButtonChrome>
</ControlTemplate>
CheckBox innerCheckBox = testButton.Template.FindName("innerCheckBox", testButton) as CheckBox;

Resources