The problem:
I would like to create a button template in XAML where I bind the image source to a content presenter content box or anything similar.
Required parameters for the solution:
I understand that for a standard button I'm able to add a stackpanel or grid to the button, insert an image into said container and call it a day. However, I'm not a fan of the windows 'chrome' look nor the blue mouse over, click, and focus effects. What I'm attempting to do is create a new button template (editing a copy of the default button template and removing the chrome container) that has the capability to be a base template with the option of changing images as I add more buttons.
Things I've tried and their results:
<Button x:Name="btn">
<StackPanel>
<Image source="imgsource.png"/>
</StackPanel>
</Button>
Result: Has the button chrome effect. Can be a fall back if nothing else possible but I don't like it.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="bContainer" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" Height="{TemplateBinding Height}" VerticalAlignment="{TemplateBinding VerticalAlignment}" Width="{TemplateBinding Width}">
<Grid x:Name="gBody" Background="#FF3C3C3C"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="ToggleButton.IsChecked" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Button Style="{DynamicResource ButtonStyle}">
<Grid>
<Image Source="imgsource.png"/>
</Grid>
</Button>
Result: The image doesn't show up. I'm thinking this is due to the button custom template, but my knowledge on this is limited so I haven't delved too deep.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="bContainer" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" Height="{TemplateBinding Height}" VerticalAlignment="{TemplateBinding VerticalAlignment}" Width="{TemplateBinding Width}">
<Image x:Name="iImage" Source="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Left" Height="16" VerticalAlignment="Top" Width="16"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="ToggleButton.IsChecked" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Button Style="{DynamicResource ButtonStyle}">
<Grid>
<Image Source="imgsource.png"/>
</Grid>
</Button>
Result: The image only shows up when entering the FULL path to the image. I'm not sure if I'm correct, but wouldn't this cause problems when deploying the program?
I'm kind of surprised your third example works - even with the full path. Just at a glance it does not seem like it should work. Your second attempt is close but you do not have a site to bind the button's content to.
Look at your button:
<Button Style="{DynamicResource ButtonStyle}">
<Grid>
<Image Source="imgsource.png"/>
</Grid>
</Button>
The Grid is the Content (the grid is not necessary - you can just put the Image there). Looking at your template you can see there is nothing in there that will pick up the content. Try adding a content presenter to your template:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="bContainer"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
Height="{TemplateBinding Height}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Width="{TemplateBinding Width}">
<ContentPresenter x:Name="contentPresenter"
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused"
Value="true"/>
<Trigger Property="ToggleButton.IsChecked"
Value="true"/>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
Related
So I created a very (and I can't stress that enough) simple program since I am just starting out learning WPF.
It's so simple, in fact, that I can write it all here:
<Window x:Class="TestWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="650" Width="825">
<Grid>
<StackPanel Width="125" Background="AliceBlue" Margin="0,10,200,10">
<Button Margin="5,5,5,5" Height="50" Width="100" Content="Tester" Background="Coral">
</Button>
</StackPanel>
</Grid>
But this program has a problem. The button flashes.
When I load up the program, the button is a coral colour (as expected). If I mouse over it, it turns back to the original colour (I guess that colour comes from the control that holds it? As you can see, I only specify one colour for the button.)
The issue comes when I click the button (left mouse). When I do this, the button transitions from one colour (coral) to the other (alice blue) over a period of about a second. It goes back and forth over and over. If I mouse over it in this state, it returns to the mouse over colour as it would do normally, but then when I take my mouse away from it, it starts flashing again.
To be clear: this is not about the change of colour on mouseover. I'm fine with that. After I click the button, said button transitions between two colours over and over again. The colours are coral and the mouse over colour, which of course I have not specified.
I am at a loss here. I've not told it to do this (have I?) I haven't clicked anything in the properties or written any code behind. The XAML is ALL that I have done.
Why on earth does the button flash?
Edit here are some images which show the entire thing. All code (there isn't any). The XAML, the app.xaml.cs, everything.
Edit 2 another image with all the button properties. I didn't change any, so far as I know.
The "flashing" you are experiencing probably comes from the default template of the Button. You can override it to make your Button look like a plain rectangle without any kind of effects:
<Button Margin="5,5,5,5" Height="50" Width="100" Content="Tester" Background="Coral">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Margin}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
This is because of the default styles in windows.
A normal button (on windows 7) transitions from a two tone grey to a two tone blue, it's triggered by the default control template.
You can edit the control template and set the style on the button..
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Class="WpfApplication1.MainWindow"
Title="MainWindow" Height="650" Width="825">
<Window.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel Width="125" Background="AliceBlue" Margin="0,10,200,10">
<Button Margin="5,5,5,5" Height="50" Width="100" Content="Tester" Background="Coral" Style="{DynamicResource ButtonStyle1}"/>
</StackPanel>
</Grid>
</Window>
You can now see where the other colours are coming from
Removing the attributes RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" from <Themes:ButtonChrome and the <ControlTemplate.Triggers> disables this behaviour
I have set a style for my MenuItems which looks like the following
App.xaml
<Style x:Key="MenuItemHover" TargetType="MenuItem">
<Setter Property="Width" Value="50"></Setter>
<Setter Property="FontFamily" Value="Calibri"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuItem">
<Border x:Name="border"
Background="#282828"
>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="Gray"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
MainWindow.xaml
<Menu x:Name="Menu_Dropdown" Width="150" Background="#282828" Foreground="White" HorizontalAlignment="Left" Grid.Column="0" Grid.ColumnSpan="2" Height="25" VerticalAlignment="Top">
<MenuItem x:Name="MenuItem_User" Height="25" Header="Nutzer" Style="{DynamicResource MenuItemHover}"></MenuItem>
<MenuItem x:Name="MenuItem_Kasse" Header="Kasse" Style="{DynamicResource MenuItemHover}"></MenuItem>
<MenuItem x:Name="MenuItem_Design" Header="Design" Style="{DynamicResource MenuItemHover}"></MenuItem>
</Menu>
When I use my style "MenuItemHover" it let the text disappear. The rest is working fine. (so the hover effect itself - it's changing the color when I move my mouse over)
Without using the style the header is getting showed normally.
There are a couple of things to make this code better, let's take a look one by one.
First of all, when you override the template, you need to know that you're not extending, but rather rewrite it; therefore you need to add the "obvious" parts as well, not just the new ones. As Anton says, you need at least one control to display the text itself. See his answer for an example.
Secondly, if you want to use the same style for every MenuItem, it is better to define the Style without a key. That way that's going to be the default style for MenuItems and it will be applied to all of them unless you say explicitly otherwise. (You don't need to add Style="{DynamicResource MenuItemHover}" to every MenuItem tag. Keep in mind that there is a hierarchy of applying styles. For example if you set the font size to 15 in the style, but then you add FontSize="50" to one of the MenuItems explicitly that MenuItem will use the value 50. See more about it here)
Last, but not least I think a good way to do this kind of changes in the styles is opening up Blend, select the control, then create a copy of the original template:
and customize that copy. (As you can see below this is just the ControlTemplate, you need to put this into a style) This way you can be sure you won't lose anything that is there originally.
Example (MenuItem ControlTemplate):
<ControlTemplate x:Key="MenuItemControlTemplate1" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<Path x:Name="GlyphPanel" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="#FF212121" FlowDirection="LeftToRight" Margin="3" Visibility="Collapsed" VerticalAlignment="Center"/>
<ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
<Setter Property="Fill" TargetName="GlyphPanel" Value="#FF707070"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="#0A000000"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#21000000"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
The relevant part in your case is:
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
You can change the background color here to achieve what you want (I changed it to Red to see it better):
You may want to change the BorderBrush color as well.
Your template should contains ContentPresenter
<Border x:Name="border"Background="#282828" >
<ContentPresenter Content="{TemplateBinding Header}"/>
</Border>
In native template of MenuItem used ContentPresenter and set ContentSource="Header"
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Height="22" SnapsToDevicePixels="true">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="13"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<Border x:Name="GlyphPanel" BorderBrush="{StaticResource MenuItem.Highlight.Border}" BorderThickness="1" Background="{StaticResource MenuItem.Highlight.Background}" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22">
<Path x:Name="Glyph" Data="{StaticResource Checkmark}" Fill="{StaticResource MenuItem.Selected.Glyph}" FlowDirection="LeftToRight" Height="11" Width="9"/>
</Border>
<!-- ContentPresenter which showing MenuItem.Header -->
<ContentPresenter x:Name="menuHeaderContainer" Grid.Column="2" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
<TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
...
</ControlTemplate.Triggers>
</ControlTemplate>
I have following Button in my c#WPF 3.5 .NET Application
<Button Height="23" x:Name="btnImportKvf" Width="75" Click="btnImportKvf_Click" IsEnabled="True" ToolTip="Click to Import" Content="Import KVF" />
My button style template applied in ResourceDirectory App.xaml as following
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna">
<!-- Focus Visual -->
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle
Margin="2"
StrokeThickness="1"
Stroke="#60000000"
StrokeDashArray="1 2"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- SimpleStyles: Button -->
<Style TargetType="Button">
<!--Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/-->
<Setter Property="Foreground" Value="{StaticResource GlyphLightBrush}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" Background="{DynamicResource BackgroundNormal}" BorderThickness="1,1,1,2" CornerRadius="4,4,4,4" BorderBrush="{DynamicResource GlyphDarkBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.507*"/>
<RowDefinition Height="0.493*"/>
</Grid.RowDefinitions>
<Border Opacity="0" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="4,4,4,4" Background="{StaticResource GlowBrush}" />
<!--ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto" Grid.RowSpan="2"/-->
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True" Grid.RowSpan="2"/>
<Border HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="4,4,0,0" Background="{DynamicResource ShineBrush}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" TargetName="border" Value="{DynamicResource DisabledForegroundBrush}"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" TargetName="border" Value="{DynamicResource GlowBrush}"/>
</Trigger>
<!--Trigger Property="LostFocus">
<Setter Property="Background" TargetName="border" Value="{DynamicResource BackgroundNormal}"/>
</Trigger-->
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="shine" Value="0.4"/>
<Setter Property="Visibility" TargetName="glow" Value="Hidden"/>
<Setter Property="Background" TargetName="border" Value="{DynamicResource GlowBrush}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource GlyphDarkBrush}" />
<Setter Property="Background" TargetName="border" Value="{DynamicResource GlowBrush}"/>
</Trigger>
<Trigger Property="IsCancel" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#FFEAEBF0" Offset="0.9"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Now I am doing localization in my project, so while changes language like french, then Button text would become big rather than button width, so I want auto texttrimming in button style. and full text display in tooltip.
Also i have second kind of button with Images and Text as following.
<Button Name="btnRefresh" Click="btnRefresh_Click" Width="69" ToolTipService.ToolTip="Click To Refresh" FontSize="11" Content="Refresh">
<Image Source="../Images/Refresh.png" Width="18" Height="13" />
</Button>
I also want to apply same style with this button too.
So is it possible to do this in same style template?
Please help me to solve this.
Thanks in Advance.
To do this, you need to change the ContentPresenter in your style to a Textblock, and bind its Text to your Content.
If you replace with something along those lines, you should be able to set text trimming as you like.
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
Background="{DynamicResource BackgroundNormal}"
BorderThickness="1,1,1,2"
CornerRadius="4,4,4,4"
BorderBrush="{DynamicResource GlyphDarkBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.507*"/>
<RowDefinition Height="0.493*"/>
</Grid.RowDefinitions>
<Border Opacity="0"
HorizontalAlignment="Stretch"
x:Name="glow"
Width="Auto"
Grid.RowSpan="2"
CornerRadius="4,4,4,4"
Background="{StaticResource GlowBrush}" />
<TextBlock Text="{TemplateBinding Content}"
TextTrimming="WordEllipsis"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Grid.RowSpan="2"/>
<Border HorizontalAlignment="Stretch"
Margin="0,0,0,0"
x:Name="shine"
Width="Auto"
CornerRadius="4,4,0,0"
Background="{DynamicResource ShineBrush}"/>
</Grid>
</Border>
...
</ControlTemplate>
EDIT: regarding the second part of your question.
The last piece of code you show cannot work as you're setting the Content of your Button twice (I don't think it actually compiles).
The cleanest way of doing what you're trying to achieve is to define a custom Control class, as described here.
A "not so clean" hack could be to use the Tag field of your Button to store the image source URI like this:
<Button Name="btnRefresh"
Click="btnRefresh_Click"
Width="69"
ToolTipService.ToolTip="Click To Refresh"
FontSize="11" Content="Refresh"
Tag="../Images/Refresh.png" Width="18" Height="13" />
And then retrieve it in your style. This Grid replaces the Textblock in the previous solution:
<Grid Grid.RowSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Tag}" />
<TextBlock Text="{TemplateBinding Content}"
Grid.Column="1"
TextTrimming="WordEllipsis"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
The reason why the binding is slightly different is explained here.
But again, creating a custom Button with image and text is probably the cleanest way to do this!
I've created style for button in my WPF app:
<Style x:Key="buttonStyle" TargetType="Button">
<Setter Property="Border.BorderBrush" Value="Black" />
<Setter Property="Border.BorderThickness" Value="1" />
<Setter Property="Border.Background" Value="White" />
<Setter Property="Height" Value="25" />
<Setter Property="Width" Value="100" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then I'm putting this style to Button control:
<Button Style="{StaticResource buttonStyle}" Grid.Row="1" Grid.Column="1" Content="Press"/>
When I'm running my app, I see grey shadow under and right of the button. Futhermore when I look in Visual Studio view I don't see shadow. How can I delete this effect? Anyone an idea or an completly other approach?
Are you sure what you're seeing is actually a shadow? It could simply be a blurred edge. WPF's layout system is based on device-independent pixels, so it's possible for an element's edge to reside between two device pixels, in which case it may appear blurred.
You can force device-pixel snapping by setting UseLayoutRounding="True" on a parent element in WPF 4.0 and later; in earlier versions, you can try SnapsToDevicePixels="True".
Look at this!
I really need to get rid of this!
Look at the delcaration!
<ListView Name="list" BorderThickness="0">
How do I fix it?
This gap doesn't only happen to the scrollbar, it also happens to the items, with or WITHOUT any views.
Looks like a problem in the Template, most likely a property of an internal control which is not bound to any of the properties the ListBox exposes to you.
Edit by Vercas: I have found the problem.
This is the template of the ListView:
<ControlTemplate x:Key="ListView" TargetType="ListBox">
<Border Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}" Name="Bd" Padding="1" SnapsToDevicePixels="True">
<ScrollViewer Focusable="False" Padding="{TemplateBinding Control.Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="Border.Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
</Trigger>
<Trigger Property="ItemsControl.IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Just change the Padding of the Border to 0 and you're done.
Here is the result if you don't want to bother finding the property.
<ControlTemplate x:Key="ListView" TargetType="ListBox">
<Border Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}" Name="Bd" Padding="0" SnapsToDevicePixels="True">
<ScrollViewer Focusable="False" Padding="{TemplateBinding Control.Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="Border.Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
</Trigger>
<Trigger Property="ItemsControl.IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Don't forget to add this template to your ListView!
This would be easier to fix in Blend if you have it. if not there is a free trial. You will have to generate a copy of the control template for the scrollviewer that you are using in that list. From there you can edit the template for the ScrollBar.
The scroll bars template is going to be several levels of templates deep once you get to it. ListView Template>ItemsPresenter (In this case a Wrap Panel) Template> ScrollViewer Template > ScrollBar Template.