I've got an iPhone image that I'd like to place a click event on the home button.
How can I accomplish this with WPF? I've tried placing a button on the image but I didn't get the desired result.
What type of control do you use for your image?
<Window.Background>
<ImageBrush ImageSource="Images/Skin/full.png" Stretch="Fill">
</ImageBrush>
</Window.Background>
You can place the image in a suitable panel like Canvas or Grid and use invisible buttons as overlay.
In resources:
<Style x:Key="InvisibleButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="Transparent" BorderBrush="Red" BorderThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage:
<Grid Width="150" Height="150">
<ImageBrush ImageSource="Images/Skin/full.png" Stretch="Fill"/>
<Button x:Name="TopLeft" Margin="0,0,100,100" Click="TopLeft_Click" Style="{StaticResource InvisibleButtonStyle}"/>
<Button x:Name="TopRight" HorizontalAlignment="Right" Click="TopRight_Click" Margin="0,0,0,100" Width="100" Style="{StaticResource InvisibleButtonStyle}"/>
<Button x:Name="BottomLeft" VerticalAlignment="Bottom" Click="BottomLeft_Click" Margin="0,0,100,0" Height="100" Style="{StaticResource InvisibleButtonStyle}"/>
<Button x:Name="BottomRight" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="BottomRight_Click" Margin="0,0,0,0" Width="100" Height="100" Style="{StaticResource InvisibleButtonStyle}"/>
</Grid>
Note I added a red border to the transparent button in order to highlight the clickable areas, in reality it would only be transparent background.
I've achieved this by doing the following:
<Canvas Height="30" VerticalAlignment="Top" Margin="0,394,0,0" Width="220">
<Button Content="" Canvas.Left="102" Canvas.Top="6" Background="Transparent" Width="16" BorderBrush="Transparent" Cursor="Hand" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Canvas>
Just have to set your margins and Canvas left and top positions to overlay the clickable area.
Since you need a part of image to be clickable, I would suggest this solution.
C/P from link...
<Canvas>
<Image Source="background.png"/>
<Ellipse Canvas.Left="82" Canvas.Top="88" Width="442" Height="216" Fill="Transparent" Cursor="Hand" MouseDown="Ellipse_MouseDown_1"/>
<Ellipse Canvas.Left="305" Canvas.Top="309" Width="100" Height="50" Fill="Transparent" Cursor="Hand" MouseDown="Ellipse_MouseDown_2"/>
</Canvas>
Related
So this is my XAML and for some reason it's not changing colors on mouseover, I added the triggers for it and I thought that would do it, when I hover over the button its not doing anything at all, why is that?
<Button Click="ButtonBase_OnClick" Margin="10,0,0,0" Style="{DynamicResource RoundedButtonStyle}" Width="100" Height="30" HorizontalAlignment="Left">
<Grid>
<Image IsHitTestVisible="False" Height="15" Width="15" VerticalAlignment="Center" HorizontalAlignment="Left" Source="Resources/addButton.png" />
<TextBlock IsHitTestVisible="False" Margin="20,0,0,1" VerticalAlignment="Center" Foreground="#9e9e9e">Add Product</TextBlock>
</Grid>
</Button>
<Window.Resources>
<Style x:Key="RoundedButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" Background="#2d2d30" BorderThickness="1" Padding="2">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
Its not changing because you modified the control template of Button to:
<Border CornerRadius="5" Background="#2d2d30" BorderThickness="1" Padding="2"
Note the hard-coded background color. No matter what you do to the button's Background property it won't take effect since its not used. If you want to use that property in your template you need a TemplateBinding:
Background="{TemplateBinding Background}"
Then in the style set the default to your original value.
<Setter Property="Background" Value="#2d2d30"/>
I want to have a button with round edge grid and set disable button color to gray, green otherwise. Attached snippet of code. I don't know how to change the default. If I disable my button, I get the output as the image on the left, however, I want it to look like the image on the right!
<Button x:Name="button" Height="30" Width="100" Margin="825,0,0,0" Background="Transparent"
BorderThickness="0" BorderBrush="Transparent">
<Button.Content>
<Border CornerRadius="12.5" Height="25" Width="95" Margin="0" BorderBrush="Gray"
BorderThickness="4,4,4,4" Background="Gray">
<TextBlock Text="Back" HorizontalAlignment="Center" VerticalAlignment="Top"
Margin="12,0,13,0" Foreground="White"/>
</Border>
</Button.Content>
</Button>
Content is only one part of Button. The rest is determined by Template.
If multiple buttons should have custom apperance, the Template should be set in buttons Style. For one button it can be done inplace:
<Button x:Name="button" Content="Back" Height="30" Width="100" Margin="825,0,0,0" Background="Transparent"
BorderThickness="0" BorderBrush="Transparent">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border CornerRadius="12.5" Height="25" Width="95" Margin="0" BorderBrush="Gray"
BorderThickness="4,4,4,4" Background="Gray">
<TextBlock Text="{TemplateBinding Content}"
HorizontalAlignment="Center" VerticalAlignment="Top"
Margin="12,0,13,0" Foreground="White"/>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
if you are going to reuse the template, declare it as Resource
<Window.Resources>
<ControlTemplate TargetType="Button" x:Key="RoundBtn">
<Border Name="roundBorder" CornerRadius="12.5" Height="25" Width="95" Margin="0" BorderBrush="Gray"
BorderThickness="4,4,4,4" Background="Gray">
<TextBlock Text="{TemplateBinding Content}"
HorizontalAlignment="Center" VerticalAlignment="Top"
Margin="12,0,13,0" Foreground="White"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="roundBorder" Property="Background" Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
and set button Template using resource:
<Button x:Name="button" Content="Back" Height="30" Width="100"
Template="{StaticResource RoundBtn}"
Margin="825,0,0,0" Background="Transparent"
BorderThickness="0" BorderBrush="Transparent"/>
This should work for you. I've used an outer grid with a blue background so that I could be sure it was all working, but just remove that and move the style to whichever resources you need to. Explanation as comments within the xaml:
<Grid Background="Blue">
<Grid.Resources>
<!-- Override the default button style, otherwise you get a grey
rectangle behind the ellipse when disabled -->
<Style TargetType="Button" x:Key="MyButtonStyle">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter x:Name="MyContentPresenter"
Content="{TemplateBinding Content}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Button x:Name="button" Height="30" Width="100"
BorderThickness="0" BorderBrush="Transparent" IsEnabled="false"
Style="{StaticResource MyButtonStyle}">
<Button.Content>
<Border CornerRadius="12.5" Height="25" Width="95">
<Border.Style>
<Style TargetType="Border">
<!-- Button is gray by default, i.e. when enabled -->
<Setter Property="Background" Value="Gray"/>
<Style.Triggers>
<!-- If the button becomes disabled then it becomes green -->
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Green" />
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="Back" HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="White"/>
</Border>
</Button.Content>
</Button>
</Grid>
I am writing a form for a WPF app, and I'd like to use the visual states that Button offers. So my XAML is like this right now:
<Button
Grid.Column="0"
Name="GenderMaleButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderThickness="0"
Padding="0">
<Border
Background="White"
BorderThickness="2"
CornerRadius="5"
Padding="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<TextBlock/>
</Border>
</Button>
But my Border is not filling my Button. How can I make the Border fill the Button? Or how can I use the visual states of the Button to affect the Border in another way than wrapping the Border inside the Button?
Or can I apply visual states to my Border? If so, how?
EDIT: the result I want is like this:
So a selected state (white border, blue bg), and a default state (blue border, white bg).
From a hard guess , I think you need to fill the border inside the button.Try the code below.Use ControlTemplate
<Button Grid.Column="0"
Name="GenderMaleButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderThickness="0"
Padding="0">
<Button.Template>
<ControlTemplate>
<Border Background="#6A6B9A"
BorderThickness="2"
CornerRadius="5"
Padding="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<TextBlock TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" Foreground="White" Text="Male"></TextBlock>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
You should have set HorizontalContentAlignment and VerticalContentAlignment to Stretch.
<Button
Grid.Column="0"
Name="GenderMaleButton"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
BorderThickness="0"
Padding="0">
<Border
Background="White"
BorderThickness="2"
CornerRadius="5"
Padding="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<TextBlock/>
</Border>
</Button>
Try this:
<StackPanel Height="40" Orientation="Horizontal">
<StackPanel.Resources>
<Style x:Key="GenderButtonStyle" TargetType="{x:Type Button}">
<Setter Property="MinWidth" Value="100" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="InternalBorder"
CornerRadius="5"
Padding="5">
<TextBlock x:Name="InternalText"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{TemplateBinding Content}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Tag" Value="Male">
<Setter TargetName="InternalBorder" Property="Background" Value="RoyalBlue" />
<Setter TargetName="InternalText" Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="Tag" Value="Female">
<Setter TargetName="InternalBorder" Property="Background" Value="White" />
<Setter TargetName="InternalBorder" Property="BorderBrush" Value="RoyalBlue" />
<Setter TargetName="InternalBorder" Property="BorderThickness" Value="1,1,1,1" />
<Setter TargetName="InternalText" Property="Foreground" Value="RoyalBlue" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<!-- Whatever you want -->
</Trigger>
<Trigger Property="IsPressed" Value="True">
<!-- Whatever you want -->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<Button x:Name="MaleButton"
Content="Male"
Style="{StaticResource GenderButtonStyle}"
Tag="Male" />
<Button x:Name="FemaleButton"
Margin="5,0,0,0"
Content="Female"
Style="{StaticResource GenderButtonStyle}"
Tag="Female" />
</StackPanel>
To explain what I've done; I placed two buttons inside a horizontal <StackPanel/> and in its resources subtag I've made a Button Style that can then be assigned to any button you want.
Inside that style I've cracked open the Template and built my own small one that does what you described.
Generally, if a control isn't looking quite the way you want as-is, the best thing to do is open up the template it's made of and make your own.
Like this, you can now define what it should look like when you mouse-over or focus it or press it.
I'm new to WPF and i have small issue. I have a button with XAML:
<Button FontSize="17" Margin="15" Background="White"
BorderThickness="0" BorderBrush="#f6f6f6"
FontWeight="DemiBold"
fluent:KeyTip.Keys="X"
CommandParameter="{Binding}"
Click="OnLoadPluginClick">
<Button.Effect>
<DropShadowEffect Opacity="0.15"/>
</Button.Effect>
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1"
Grid.Row="0" Margin="5,10,0,0" Height="180" Width="180" VerticalAlignment="Top"
Background="{TemplateBinding Background}"
HorizontalAlignment="Left" >
<Grid Height="180" Width="180" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Margin="10,10,0,0" FontSize="15" FontStretch="ExtraCondensed" Height="20" VerticalAlignment="Top"
HorizontalAlignment="Left" Text="{Binding Name}" />
<Image Stretch="Uniform" Width="70" Height="70" Grid.Row="1" HorizontalAlignment="Center"
VerticalAlignment="Center" Source="{Binding ImageSource}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="WhiteSmoke" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="WhiteSmoke" Opacity="0.6" BlurRadius="20"/>
</Setter.Value>
</Setter>
<!--<Setter TargetName="Border" Property="Background" Value="LightGreen"></Setter>-->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
As you can see i have my own triggers, but i can't the appeareance i want (shadows when mouse is on button). I get something like this:
as you can see, i have only my margins highlighted with akward gray color...
What i need: when mouse is on button border, the border gets bigger shadow, when border is pressed, it's background is set to WhiteSmoke
Something like this, but with image:
How can i implement this button correctly?
I'll be gratefull for any help.
Set TargetName=Border in the setter tag of IsMouseOver Trigger. It may work..
In our WPF application we have a common control template which we use to display errors in a consistent way
<ResourceDictionary>
<ControlTemplate x:Key="ErrorTemplate">
<Border BorderThickness="1" BorderBrush="Red">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
</ResourceDictionary>
Elsewhere in our application when a control might display an error we set the ErrorTemplate like so
<TextBox Validation.ErrorTemplate="{DynamicResource ErrorTemplate}" />
I now want to display a tool tip in this error template, however setting the tooltip property on the border doesn't help that much as the tooltip only displays when the user mouses over the 1px wide border, not the control itself which is in error.
I know that I can set the tooltip in a style, however this error template is applied to many different controls (combo boxes etc...) and many of these controls also use styles which are independent from my error template - I really want to be able to apply my error template in a generic way to any control.
Is there any way that I can set a tooltip in my ErrorTemplate?
I have a style defined. I have IDataErrorInfo on my object (Customer) which does the validation for the property(LastName) which is databound to a text box for example. Here's my style:
<Style x:Key="ValidationTextBox" TargetType="{x:Type Control}">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,2,40,2"/>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Border Background="#B22222" DockPanel.Dock="Right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
<TextBlock Text="!" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" Foreground="White"/>
</Border>
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center">
<Border BorderBrush="#B22222" BorderThickness="1" />
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style
<TextBox Style="{StaticResource ValidationTextBox}" Text="{Binding Path=Customer.LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" />
As I stated in my answer here you can:
<ControlTemplate x:Key="ErrorTemplate">
<Border BorderThickness="1" BorderBrush="Red"
Background="Transparent"
ToolTip="{Binding Path=/ErrorContent}">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
I'm sorry I didn't have time yesterday...Would you try below and see if this is what you are after, please?
<Style x:Key="ValidationTextBox2" TargetType="{x:Type Control}">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Red" BorderThickness="2">
<DockPanel LastChildFill="True" ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" Background="Transparent">
<TextBlock />
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center">
</AdornedElementPlaceholder>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>