I have created button style in wpf form
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<Button Background="Blue" FontStyle="Normal"
Padding="8,4" Margin="4" Foreground="White" FontWeight="Bold" Click="Button_Click">Prabhu
</Button>
</StackPanel>
I need to call this same style in 10 buttons. how to call the same style in all buttons?
use the resources of whateve rtop level element you want to use:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="Button" x:Key="ButtonStyle">
<Setter Property="Background" Value="Blue"></Setter>
<Setter Property="FontStyle" Value="Normal"></Setter>
<Setter Property="Padding" Value="8,4"></Setter>
<Setter Property="Margin" Value="4"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="FontWeight" Value="Bold"></Setter>
</Style>
</StackPanel.Resources>
<Button>Default Styled Button</Button>
<Button Style="{StaticResource ButtonStyle}">Fancy Blue Button</Button>
</StackPanel>
if this is going to be a global style, or you want it accessible in your entire application, i recommend creating a resource dictionary and putting it in there. then in your app.xaml, reference the resource dictionary. this article goes more in depth on that topic
Related
Good day,
I have several buttons in my WPF application that use a pre-made style template.
In this template is once the content (text) and an image.
This image should be, depending on the button, a different one or no one.
The "Settings_Button" uses the style of the "Pagebutton".
This style contains how the button is built. There is also an Image in it. How do I access the source property of the image?
Unfortunately I haven't found a solution for this online and I'm still relatively new in this area.
[The Style Template, the Buttons are using]
<!--PageButton-->
<Style x:Key="Pagebutton" TargetType="Button">
<Setter Property="Width" Value="200"/>
<Setter Property="FontFamily" Value="{StaticResource Roboto}"/>
<Setter Property="Foreground" Value="{DynamicResource FntBtnColor_Page}"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="5 5 5 5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="borderBtn" CornerRadius="3" Background="#E00047" >
<Grid>
<Image x:Name="Pagebutton_Image" HorizontalAlignment="Right" Height="15" Width="15" Margin="0 0 20 0"/>
<ContentPresenter x:Name="contentPresenterBtn" HorizontalAlignment="Center" VerticalAlignment="Center" Focusable="False" RecognizesAccessKey="True"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
[The Usage of the Style]
<Button x:Name="Settings_Button" Style="{DynamicResource Menuebutton}" Content="{x:Static p:Resources.Menue_settings}" Click="Settings_Click"/>
I have some buttons -in different windows- that have the same content. But if two windows surfaced together,out of the first window's button content disappears.
Buttons Style is :
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
button Code in windows is :
<Button Style="{DynamicResource BSaveBtn}" Template="{DynamicResource FlatGreenBtnHover}" />
problems occurs only with content -not another style properties- .
Seems to work fine for me when I tested it here.
A few things I noticed though that may help. You don't need them to be DynamicResource, they should really be StaticResource unless you plan on modifying them.
I assume you are declaring these in the Windows.Resource section or repeating them on each window?
If so you should centralize those to a ResourceDictionary.
Create a new Resource Dictionary put your style in there like so:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Then in your App.xaml put the following:
<ResourceDictionary>
<ResourceDictionary Source="MyResources.xaml" />
</ResourceDictionary>
The Image should really be in a dictionary to avoid loading it multiple times. Just add a line in that ResourceDictionary like so:
<BitmapImage UriSource="/login;component/Images/Save.png" x:Key="Save" PresentationOptions:Freeze="True" />
Setting the PresentationOptions:Freeze will also help if the image is never being modified.
Your call to the image would then change to be:
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="{StaticResource Save}"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
Once your resources are centralized in a ResourceDictionary (or multiple) it makes it easy to apply those same styles anywhere in your application and hopefully will help with your issue. If not please give more info on the problem you have such as sample code to make the issue happen please.
An instance of an element can only appear once in the visual tree. You can set the x:Shared attribute of the Style to False in order for a new instance of the StackPanel to get created for each Button to which you apply the style:
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn" x:Shared="False">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
I'm trying to do the html to xaml convertor and use this code as a starting point. My app is Windows Phone 8.1 universal app. This code works very good except the hyperlinks. It looks like HyperlingButton have some hidden margin or padding and I can't fix it in the style by setting it to 0.
The hyperlink is marked with red border:
My style is here:
<Style TargetType="HyperlinkButton" x:Key="UnderlineHyperlinkButton">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontFamily" Value="{ThemeResource PhoneFontFamilyNormal}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HyperlinkButton">
<TextBlock Style="{StaticResource TextStylePostBody}">
<Underline>
<Run Text="{Binding Path=Content, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</Underline>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Style for TextBlock:
<Style x:Key="TextStylePostBody" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="Margin" Value="0,0,0,0"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="TextTrimming" Value="WordEllipsis"/>
<Setter Property="TextWrapping" Value="WrapWholeWords"/>
</Style>
I can fix it with hardcoded values in margin <Setter Property="Margin" Value="0,-9, 4,-4"/> but it does not looks good.
The code that creates hyperlink is here:
private static Inline GenerateHyperLink(HtmlNode node)
{
Span s = new Span();
InlineUIContainer iui = new InlineUIContainer();
HyperlinkButton hb = new HyperlinkButton() { NavigateUri = new Uri(node.Attributes["href"].Value, UriKind.Absolute), Content = CleanText(node.InnerText) };
hb.Style = ( Style )Application.Current.Resources[ "UnderlineHyperlinkButton" ];
iui.Child = hb;
s.Inlines.Add(iui);
return s;
}
Is there something that I missed?
Update:
Did a quick test with this XAMl code:
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Foreground="Black" FontSize="18" FontWeight="Normal" FontFamily="Segroe UI">TextBlock</TextBlock>
<RichTextBlock>
<Paragraph>
<Run Foreground="Black" FontSize="18" FontWeight="Normal" FontFamily="Segroe UI">
<Run.Text>Run text</Run.Text>
</Run>
<InlineUIContainer>
<HyperlinkButton FontSize="18" FontFamily="Segroe UI" FontWeight="Normal" Margin="0" Padding="0,0,0,0">Link Text</HyperlinkButton>
</InlineUIContainer>
</Paragraph>
</RichTextBlock>
</StackPanel>
and got this:
Setting Margin of HyperlinkButton to -9 (Top):
It's not the problem of other text or InlineUIContainer, replacing HyperlinkButton with TextBlock fixes the margins:
Decided to avoid InlineUIContainer and HyperlinkButton due to align and formatting problems. I have replaced it with <Underline> with Link attached property. More info in this article.
EDIT: Don't know why, but I missed that runtime API have a dedicated Hyperlink class that do the job very well.
I'm still a little green when it comes to WPF. I'm currently working on a WPF form that has several text boxes on it. Each of those TextBoxes are paired with a TextBlock sitting in the same x,y coord, acting as GhostText. Once you click inside the TextBox the GhostText disappears.
Below is an example of how the binding was originally setup in the form's XAML (this same code is duplicated for all text boxes thus the reasoning behind using a style) :
<TextBox Grid.Column="0" Width="40" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" x:Name= "RecordMinutesTextBox" Padding="12,5,5,0" Text ="{Binding RecordMinute}" Margin="0,25,5,1" PreviewTextInput="CheckNumberValidation" Background="{Binding ElementName=FireWashingtonResponseTimeReport,Path=DataContext.RequiredFieldColor}"/>
<TextBlock Grid.Column="0" Width="40" IsHitTestVisible="False" Text="MIN" VerticalAlignment="Center" HorizontalAlignment="Left" Foreground="DarkGray" Margin="8,25,0,1" >
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=RecordMinutesTextBox}" Value="">
<Setter Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
*Note the name of one of the many text boxes,"RecordMinutesTextBox", used as the ElementName for the DataTrigger Binding.
Here is the code from inside my WPF Style template:
<Style x:Key="MinuteAndSecondsGhostText" TargetType="TextBlock">
<Setter Property="Width" Value="40"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Foreground" Value="DarkGray"/>
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=??WhatDoIPutHere??}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>enter code here
So my question really comes down to this. What should I use in the DataTrigger Binding as the ElementName for this style? Considering that I have multiple TextBoxes with different names on my form. Thanks in advance.
I give you an idea... and you can change your codes base on it.
In my following sample you see the TextBlock shows state of IsFocused property of the TextBox. So you can put the pair of your elements in a parent like StackPanel and access to properties of one child in another child by RelativeSource instead of ElementName...
Just put this codes in your window and focus in TextBox, What you see inside the TextBlock?
<StackPanel Orientation="Horizontal" Background="White" Margin="20">
<TextBox Text="" Name="TextBox" Background="DarkSalmon" Width="100" Height="30"/>
<TextBlock Text="{Binding Path=Children[0].IsFocused,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type StackPanel}}}"
Margin="20,0"/>
</StackPanel>
Edit:
Base on my above idea you can use RelativeSource instead of ElementName to resolve your problem like the following sample:
<Style x:Key="MinuteAndSecondsGhostText" TargetType="TextBlock">
<Setter Property="Width" Value="40"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Foreground" Value="DarkGray"/>
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Children[0].Text,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type StackPanel}}}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
And in your Window body:
<StackPanel x:Name="Pair1" Orientation="Horizontal" Background="White" Margin="20">
<!--TextBox should be first child of StackPanel-->
<TextBox Text="" Name="TextBox1" Background="DarkSalmon" Width="100" Height="30"/>
<TextBlock Text="Sample Text" Style="{StaticResource MinuteAndSecondsGhostText}" Margin="20,0"/>
</StackPanel>
<StackPanel x:Name="Pair2" Orientation="Horizontal" Background="White" Margin="20">
<!--TextBox should be first child of StackPanel-->
<TextBox Text="" Name="TextBox2" Background="DarkSalmon" Width="100" Height="30"/>
<TextBlock Text="Sample Text" Style="{StaticResource MinuteAndSecondsGhostText}" Margin="20,0"/>
</StackPanel>
Im coming from a C# winforms background and I would normally do all this in code.
I have several Labels that I'm using as a menu.
When the mouse hovers over them the text changes color by:
<Page.Resources>
<SolidColorBrush x:Key="normalColor" Color="White" />
<SolidColorBrush x:Key="mouseOverColor" Color="Gold" />
<Style TargetType="Label" x:Key="menuItemStyle">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Foreground" Value="{StaticResource normalColor}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource mouseOverColor}"/>
</Trigger>
</Style.Triggers>
</Style>
</Page.Resources>
<Label x:Name="Label_Video1" Style="{StaticResource menuItemStyle}" Content="1.Video 1." FontSize="16" HorizontalAlignment="Left" Margin="25,74,0,0" VerticalAlignment="Top" MouseLeftButtonDown="Label_Video1_MouseLeftButtonDown" />
<Label x:Name="Label_Video2" Style="{StaticResource menuItemStyle}" Content="2. Video 2." FontSize="16" HorizontalAlignment="Left" Margin="25,105,0,0" VerticalAlignment="Top" MouseDown="Label_Video2_MouseDown"/>
When the user clicks a label I want it to stay a certin color (In this case Gold) and all the others to stay their normal colour. So if a label has been previously clicked and I click another label it will go from gold to white etc
When using WPF, you have to think slightly differently. We know that the Label control doesn't know when it has been clicked and it especially doesn't know when another Label element has been clicked... but some controls do. Thinking about it... a RadioButton has exactly this behaviour. Now this is where WPF really shines.
We can use RadioButtons and by providing them with a new ControlTemplate, we can make them look like plain text:
<Grid Background="Black">
<Grid.Resources>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<TextBlock Text="{TemplateBinding Content}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="White" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource AncestorType={
x:Type RadioButton}}}" Value="True">
<Setter Property="Foreground" Value="Gold" />
</DataTrigger>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource
AncestorType={x:Type RadioButton}}}" Value="True">
<Setter Property="Foreground" Value="Gold" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<StackPanel Margin="5" Background="{x:Null}">
<RadioButton Content="1.Video 1." />
<RadioButton Content="2.Video 2." />
<RadioButton Content="3.Video 3." />
</StackPanel>
</Grid>
If you don't want the RadioButtons to be all together in a StackPanel, then you can use give them the same GroupName property value to ensure that they still operate as one group.