Use a ContentPresenter for personnalize a template - c#

I created a ressourceDictionnary for creating a templateButton.
I would like to be able to change the png image when i use this template, i think i need to use a ContentPresenter, but i don't know why.
Here is my RessourceDictionnary :
<ControlTemplate TargetType="{x:Type Button}" x:Key="BoutonRessources">
<Button Width="32" Margin="0,0,7,0" Name="tbrClear" ToolTip="Clear" VerticalAlignment="Center" BorderThickness="0" HorizontalAlignment="Center" Background="Transparent" HorizontalContentAlignment="Center">
<Border>
<Image Source="xRtDiva_XWPF_TBR_PREMIER.PNG_IMAGES.png" Height="18"/>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="BoutonToolbarSelected.png"/>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="22"/>
<Setter Property="Width" Value="32"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</Button>
So, when i use this Button template, i would like to be able to pass them an other png image to display. For example i would like to replace xRtDiva_XWPF_TBR_PREMIER.PNG_IMAGES.png by MyPicture.png.
How doing this ? With a contentPresenter ?
Thanks :)

Related

Hover rounded corner button change its background color using ResourceDictionary

I have created a ResourceDictionary style sheet that have a style named btn_default.
I plan to use it on all the buttons in my program. My problem is that when I hover the button then the background-color doesnt change. The font color changes.
button_default
button_default:hover
I tried in my code to change the "Setter Property="Background" Value="#b5b5b5"", however I guess that doesnt affect the Border-tag, but the Style-tag?
ResourceDictionary
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MSDNSample">
<!-- Btn default -->
<Style x:Key="btn_default" TargetType="{x:Type Button}">
<Setter Property="FontFamily" Value="Calibri"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Foreground" Value="#d9d9d9" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" BorderThickness="1" Padding="6,4,6,4" Background="#6c6c6c" BorderBrush="#393939">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#b5b5b5"/>
<Setter Property="Foreground" Value="#000000" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- //Btn default -->
</ResourceDictionary>
Main
<Button x:Name="buttonExplorer" Content="Explorer" Style="{StaticResource btn_default}" Margin="0,0,6,0" />
<Button x:Name="buttonProcess" Content="Process" Style="{StaticResource btn_default}" Margin="0,0,6,0" />
You should declare Background property of Border using TemplateBinding extension and set Background value in Style setter, otherwise it'll never be updated
<Style x:Key="btn_default" TargetType="{x:Type Button}">
<Setter Property="FontFamily" Value="Calibri"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Foreground" Value="#d9d9d9" />
<Setter Property="Background" Value="#6c6c6c"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" BorderThickness="1" Padding="6,4,6,4" BorderBrush="#393939" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#b5b5b5"/>
<Setter Property="Foreground" Value="#000000" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF - 300+ buttons on UI - really slow... what's the alternative?

I've got about 300+ buttons that are represented in a grid. When I try to render this, it takes a good 5 seconds to load up all buttons. Is there any alternative? Functionality that already exists such as hover over, mouse enter, left button click etc are all needed... just wondering if there is a way to speed up button rendering.
Buttons are created dynamically in a grid, with an ItemsControl, that contains an ItemsPanelTemplate (that is just a grid definition of width and height), a DataTemplate in ItemsControl.Resources, where the ToggleButton(s) that are created dynamically (300+) are created.
The datatemplate in the ItemsControl.Resources looks like this:
<DataTemplate DataType="{x:Type engine:Weodel}">
<ToggleButton
Tag="{Binding}"
IsChecked="{Binding IsSelected}"
Height="{Binding ElementName=weItemControl,
Path=DataContext.ButtonHeightWidth}"
Width="{Binding ElementName=weItemControl,
Path=DataContext.ButtonHeightWidth}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Margin="{Binding ElementName=weItemControl,
Path=DataContext.ButtonMarginToUse}"
Padding="2"
Style="{StaticResource WeButton}">
</ToggleButton>
</DataTemplate>
The style of the button in resource dictionary:
<Style TargetType="{x:Type ToggleButton}" x:Key="WeButton">
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" TextBlock.TextAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="TextAlignment" Value="Center"/>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" Value="{Binding GColour}"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="{Binding GColour}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF - Font Awesome icons not showing in runtime

I'm building WPF application and I want to use icons from Font Awesome. I have Font Awesome included in styles, and a font family specified in fields where I want to use it. The problem is icons are showing properly in the design window but change to crossed squares during runtime.
There is my Fonts XAML
<FontFamily x:Key="ArconRegular">pack://application;,,,/Fonts/#Arcon</FontFamily>
<FontFamily x:Key="ArconRounded">pack://application;,,,/Fonts/#Arcon Rounded-</FontFamily>
<FontFamily x:Key="FASolid">pack://application;,,,/Fonts/#Font Awesome 5 Free Solid</FontFamily>
<Style TargetType="{x:Type Control}" x:Key="BaseStyle">
<Setter Property="FontFamily" Value="{StaticResource ArconRegular}"/>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="BaseTextBlockStyle">
<Setter Property="FontFamily" Value="{StaticResource ArconRegular}"/>
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource BaseStyle}"/>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource BaseStyle}"/>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource BaseStyle}"/>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseTextBlockStyle}"/>
<Style TargetType="{x:Type ListView}" BasedOn="{StaticResource BaseStyle}"/>
<system:String x:Key="FAMinimizeIcon"></system:String>
<system:String x:Key="FAMaximizeIcon"></system:String>
<system:String x:Key="FACloseIcon"></system:String>
The Buttons XAML (I want to use icons on buttons)
<Style TargetType="{x:Type Button}" x:Key="WindowControlButton" BasedOn="{StaticResource BaseStyle}">
<Setter Property="FontFamily" Value="{StaticResource FASolid}"/>
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="Foreground" Value="{StaticResource ForegroundMainBrush}"/>
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.5"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource BackgroundLightBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
And finally MainWindow XAML (a part of it where i want to use them)
<!-- Window Buttons -->
<StackPanel Grid.Column="2" Orientation="Horizontal">
<Button Style="{StaticResource WindowControlButton}" Content="{StaticResource FAMinimizeIcon}" Command="{Binding MinimizeCommand}"/>
<Button Style="{StaticResource WindowControlButton}" Content="" Command="{Binding MaximizeCommand}"/>
<Button Style="{StaticResource WindowCloseButton}" Content="" Command="{Binding CloseCommand}"/>
</StackPanel>
As you can see, I tried specifying icon code in separate string and using StaticResource but nothing works.
In my case it was missing FontFamily="{TemplateBinding FontFamily}" in the ControlTemplate
Had a same issue, i.e Showing ok in Design mode but no Runtime. For me it was because fontawesome was not included in the assembly.
Changed (in visual studio) the .otf file's Build Action to "Resource". You may want to check if the file is included in your assembly by decompiler.

MouseOver effect for button in DataTemplate

I use a DataTemplate to show some buttons with a customized view (with an image, text, etc). Here is a simplified example:
<DataTemplate DataType="{x:Type viewModel:ActionItem}">
<Button Background="SlateGray" Command="{Binding Command}">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<TextBlock Text="{Binding Name}" />
</Button>
</DataTemplate>
Why is the mouse over effect not working at all?
Because Background="SlateGray" overrides anything you can trigger in a Style. Remove that bit and it should work.
Please set the trigger at at the template level like
<DataTemplate DataType="{x:Type viewModel:ActionItem}">
<Button Background="SlateGray" Command="{Binding Command}">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
<TextBlock Text="{Binding Name}" />
</Button>
</DataTemplate>

ToggleButton Trigger IsChecked Doesn't Change Background

I have a ToggleButton with a red background. I need to set a green background when the toggle button is checked.
I've tried this:
<ToggleButton Content="Test 001" Name="btn03" Height="20">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Background" Value="#ff0000" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="#00ff00" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
But instead a green color I get a light blue color (I think is the default color of my
system).
What I'm doing wrong and how to fix it?
WPF 4.0 doesen't allow this. Look here for a different approach:
<Grid>
<Grid.Resources>
<Style x:Key="ToggleButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="border" Background="Red">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" TargetName="border" Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<ToggleButton Content="ToggleButton" Style="{StaticResource ToggleButtonStyle}"/>
</Grid>

Categories

Resources