How define style in App.xaml Xamarin Forms for CustomButton? - c#

How I can define style in App.xaml for CustomButton?
App.xaml
<Style x:Key="CustomButtonSmall" TargetType="CustomButton">
<Setter Property="FontSize" Value="14" />
</Style>
MyPage.xaml
<local:CustomButton Text="{i18n:Translate CreateAccountButton}"
Grid.Column="0" Command="{Binding CreateAccountCommand}"
Type="Normal" Style="{StaticResource CustomButtonSmall}" />

You define the style in for example Window.xaml:
<Window>
<Window.Resources>
<Style x:Key="myStyle" TargetType="Button">
<Setter Property="Background" Value="Orange" />
<Setter Property="FontStyle" Value="Italic" />
</Style>
</Window.Resources>
Then u target ur button with this:
<Button Style="{StaticResource myStyle}">Buttontext</Button>

In App.xaml
Give CustomButton whole path like TargetType="Control:CustomButton"
and define Control at the top like
xmlns:Control="clr-namespace:xyz"
<Style x:Key="CustomButtonSmall" TargetType="Control:CustomButton">
<Setter Property="FontSize" Value="14" />
</Style>

Related

WPF: Global resource accessible by key

I'm styling the Grid controls to be the table headers using resources like so:
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Padding" Value="5,10" />
<Setter Property="Foreground" Value="{StaticResource ForegroundDarkBrush}" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
<Style TargetType="Border">
<Setter Property="BorderThickness" Value="0.0,1.0,0.0,0" />
<Setter Property="BorderBrush" Value="{StaticResource ForegroundDarkBrush}" />
<Setter Property="Background" Value="{StaticResource BackgroundLightBrush}" />
</Style>
</Grid.Resources>
The thing is, I need to apply that resources into multiple places in my app, which leads to the code being repeated.
I was wondering if this is possible to store the resources in my App.xaml and use them by the key or something like that? Like so:
<Resources Key="MyResourceSet">
<Style>
[..]
</Style>
</Resources>
<Grid Resource="MyResourceSet">
[...]
</Grid>
Place the Style in the App.Resources like you would in any other UIElement.
<Application x:Class="Question_Answer_WPF_App.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="MyButtonStyle"
TargetType="Button">
<Setter Property="Background"
Value="Green" />
<Setter Property="Height"
Value="30" />
<Setter Property="Width"
Value="100" />
</Style>
</Application.Resources>
</Application>
Reference wherever you want in your app.
<Window x:Class="Question_Answer_WPF_App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="800">
<Button Content="Testing"
Style="{StaticResource MyButtonStyle}" />
</Window>
Another way to do this if you want several ResourceDictionary's to be used across your app; but with the same inner keys, is to reference the unique ResourceDictionary per element that will use it. This will not be using the App.xaml resources but will be pointing directly to the file location in your application. Since ResourceDictionary's have a default 'Build Action' of 'Page' it will work referencing the location this way. If your ResourceDictionary doesn't work this way the first thing is to check this by right clicking the ResourceDictionary in your solution explorer and make sure that's correct.
Example:
MyCustomResourcesA.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="TextBlock">
<Setter Property="FontSize"
Value="46" />
</Style>
<Style x:Key="MyButtonStyle"
TargetType="Button">
<Setter Property="Background"
Value="Green" />
<Setter Property="Height"
Value="30" />
<Setter Property="Width"
Value="100" />
</Style>
</ResourceDictionary>
MyCustomResourcesB.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Question_Answer_WPF_App">
<Style TargetType="TextBlock">
<Setter Property="FontSize"
Value="26" />
</Style>
<Style x:Key="MyButtonStyle"
TargetType="Button">
<Setter Property="Background"
Value="Blue" />
<Setter Property="Height"
Value="20" />
<Setter Property="Width"
Value="200" />
</Style>
</ResourceDictionary>
MainWindow.xaml
<Window x:Class="Question_Answer_WPF_App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="800">
<StackPanel HorizontalAlignment="Left">
<StackPanel>
<StackPanel.Resources>
<ResourceDictionary Source="MyCustomResourcesA.xaml" />
</StackPanel.Resources>
<TextBlock Text="I'm using MyCustomResourcesA" />
<Button Content="Testing"
Style="{StaticResource MyButtonStyle}" />
</StackPanel>
<StackPanel>
<StackPanel.Resources>
<ResourceDictionary Source="MyCustomResourcesB.xaml" />
</StackPanel.Resources>
<TextBlock Text="I'm using MyCustomResourcesB" />
<Button Content="Testing"
Style="{StaticResource MyButtonStyle}" />
</StackPanel>
</StackPanel>
</Window>
Looks like:

How to set one content to several buttons in WPF

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>

wpf create style for named element

Is it possible to add style to xaml element without editing the element?
for example:
xaml element:
<Grid>
<Grid x:Name="A">content A</Grid>
<Grid x:Name="B">content B</Grid>
</Grid>
and style:
<Style x:Key="StyleForA" TargetName="A" TargetType="{x:Type Grid}" >
<Setter Property="Background" Value="Red"/>
</Style>
<Style x:Key="StyleForB" TargetName="B" TargetType="{x:Type Grid}" >
<Setter Property="Background" Value="Green"/>
</Style>
UPD:
I have a project with a lot of styles (aero, black, etc ).
And if I edit the element Style="{StaticResources StyleForA}" I must edit all styles.
So I need to create local style that affected to named element.
Natively you can't.
But without touching your XAML, you can do it very easily using code :
Grd1.Style = (Style) this.Resources["GridKey"];
Pure XAML approach using Blend behaviors,
<Grid x:Name="Grd1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<ic:ChangePropertyAction PropertyName="Style" Value="{DynamicResource GridKey}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Grid>
Yes. I use this style on my App.xaml to add a teplate around all aplication controls with error:
<Style x:Key="BordaTemplate" TargetType="Control">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder Name="myControl"/>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="TextBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="PasswordBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="DataGrid" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="ListBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="CheckBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="ComboBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="DatePicker" BasedOn="{StaticResource BordaTemplate}" />
Not like as you have defined using target but if you want to apply a style to a specific control. then use below:
<StackPanel>
<Button x:Name="A">
<Button.Resources>
<Style TargetType="{x:Type Button}" >
<Setter Property="Background" Value="Red"/>
</Style>
</Button.Resources>
content A</Button>
<Button x:Name="B">
<Button.Resources>
<Style TargetType="{x:Type Button}" >
<Setter Property="Background" Value="Green"/>
</Style>
</Button.Resources>
content B</Button>
</StackPanel>
Or probably create a base style and then create a BasedOn style for your controls.
Update: If you only want to be concerned about the style at a time and be sure of impacted elements:
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="First" >
<Setter Property="Background" Value="Red"/>
</Style>
<Style TargetType="{x:Type Button}" x:Key="Second" >
<Setter Property="Background" Value="Green"/>
</Style>
</Window.Resources>
<StackPanel>
<Button x:Name="A">
<Button.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource First}" />
</Button.Resources>
content A</Button>
<Button x:Name="B">
<Button.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource Second}" />
</Button.Resources>
content B</Button>
</StackPanel>
I think you can have a default style and you can override the properties you want on your local style.
<Grid>
<Grid.Resources>
<Style TargetType="Button" x:Key="Default">
<Setter Property="Background" Value="White"></Setter>
<Setter Property="Foreground" Value="Blue"/>
</Style>
<Style x:Key="StyleForA" BasedOn="{StaticResource Default}" TargetType="Button" >
<Setter Property="Background" Value="Red" ></Setter>
</Style>
<Style x:Key="StyleForB" BasedOn="{StaticResource Default}" TargetType="Button" >
<Setter Property="Background" Value="Green" ></Setter>
</Style>
</Grid.Resources>
<StackPanel>
<Button Style="{StaticResource StyleForA}" Width="100" x:Name="A" Click="Button_Click" Height="100">Test A</Button>
<Button Style="{StaticResource StyleForB}" Width="100" x:Name="B" Click="Button_Click" Height="100">Test B</Button>
</StackPanel>
</Grid>

Setting the Header of GroupBox in a GroupBox style

I'm getting XAML parse exceptions when using a certain GroupBox Style more than once. I'm keeping the style in UserControl.Resources.
Here is an example of a simplified style that does not cause a XAML parse exception:
<Style x:Key="MyGroupBoxStyle" TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Header" Value="Hello World!" />
</Style>
Here is another one that does not cause a problem.
<Style x:Key="MyGroupBoxStyle" TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Header">
<Setter.Value>
Hello World!
</Setter.Value>
</Setter>
</Style>
This one however does cause a problem:
<Style x:Key="MyGroupBoxStyle" TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Header">
<Setter.Value>
<TextBlock Text="Hello World!" />
</Setter.Value>
</Setter>
</Style>
Again, it's only a problem when I use the style on more than one GroupBox. If I use it just once, I don't get the XAML parse exception. And it doesn't have to be just a TextBlock. I think it's any UIElement.
Any ideas? Thanks!
You cannot set the content of the header to another UI control in the style. Try creating a datatemplate.
<Window.Resources>
<Style x:Key="MyGroupBoxStyle" TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="Hello World!!!!!!"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<GroupBox Style="{StaticResource MyGroupBoxStyle}" Height="200" Width="200"/>
<GroupBox Style="{StaticResource MyGroupBoxStyle}" Height="200" Width="200"/>
</StackPanel>

Apply Style to all child-elements of specific type

I want to write a style for wpf where all buttons in a StatusBar (that has a defined style) have the same style (e.g. width).
Here is what my style looks like:
<Style TargetType="{x:Type StatusBar}"
x:Key="DialogBoxStatusBarStyle">
<Setter Property="Background"
Value="LightGray" />
<Setter Property="Padding"
Value="5" />
...?
</Style>
And the xaml for the elements:
<StatusBar Style="{StaticResource ResourceKey=DialogBoxStatusBarStyle}" Grid.Row="3"
FlowDirection="RightToLeft">
<Button Content="Übernehmen"
Width="100"
HorizontalAlignment="Right" />
<Button Content="Abbrechen"
Width="100"
HorizontalAlignment="Right" />
<Button Content="OK"
Width="100"
HorizontalAlignment="Right" />
</StatusBar>
In the final version I don't want to set width to 100 for all buttons. This should be defined in the style of the StatusBar or better say in the style of the button-childs of the StatusBar.
You could add a default Style for Buttons to the Resources of your DialogBoxStatusBarStyle:
<Style TargetType="StatusBar" x:Key="DialogBoxStatusBarStyle">
<Style.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="100"/>
</Style>
</Style.Resources>
...
</Style>
To extend on the answer above (#Clemens), you could even do something like this, to reuse a button style independently, and also apply it to children of a specific container.
Styles:
<Style TargetType="{x:Type Button}" x:Key="MyButtonStyle">
<Setter Property="Width" Value="100" />
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
<Style TargetType="{x:Type StatusBar}" x:Key="DialogBoxStatusBarStyle">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Padding" Value="5" />
<Style.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource MyButtonStyle}" />
</Style.Resources>
...
</Style>

Categories

Resources