I have the below code which is basically the default tabbed view with an added style that sets back color to green instead of the dynamic primary.
<Shell.Resources>
<ResourceDictionary>
<Style x:Key="BaseStyle" TargetType="Element" >
<Setter Property="Shell.BackgroundColor" Value="{DynamicResource Primary}" />
<Setter Property="Shell.ForegroundColor" Value="White" />
<Setter Property="Shell.TitleColor" Value="White" />
<Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
<Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
<Setter Property="Shell.TabBarBackgroundColor" Value="{DynamicResource Primary}" />
<Setter Property="Shell.TabBarForegroundColor" Value="White"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
<Setter Property="Shell.TabBarTitleColor" Value="White"/>
</Style>
<Style x:Key="GreenStyle" TargetType="Element" >
<Setter Property="Shell.BackgroundColor" Value="Green" />
<Setter Property="Shell.ForegroundColor" Value="White" />
<Setter Property="Shell.TitleColor" Value="White" />
<Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
<Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
<Setter Property="Shell.TabBarBackgroundColor" Value="Green" />
<Setter Property="Shell.TabBarForegroundColor" Value="White"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
<Setter Property="Shell.TabBarTitleColor" Value="White"/>
</Style>
<Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
<Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}" />
</ResourceDictionary>
</Shell.Resources>
I want to know if it is possible to change the TabBar BasedOn property programmatically to the GreenStyle. Such as:
*Trigger*
{
TabBar.BasedOn = GreenStyle;
}
But in a way that actually works.
I am asking because it does not seem to work dynamically due to the static nature of it and it will not let me change it to a:
<Style TargetType="TabBar" BasedOn="{DynamicResource BaseStyle}" />
Any workarounds accepted so long as I can change the color/style to green from whatever color it is set to and back. I am very new to Xamarin forms.
Is there a way to change the style basedon property programmatically?
For this, you can use Dynamic Styles to achieve this function.
Applications can respond to style changes dynamically at runtime by using dynamic resources.
You can refer the following code:
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="baseStyle" TargetType="View">
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>
<Style x:Key="blueSearchBarStyle" TargetType="SearchBar" BasedOn="{StaticResource baseStyle}">
<Setter Property="FontAttributes" Value="Italic" />
<Setter Property="PlaceholderColor" Value="Blue" />
</Style>
<Style x:Key="greenSearchBarStyle" TargetType="SearchBar">
<Setter Property="FontAttributes" Value="None" />
<Setter Property="PlaceholderColor" Value="Green" />
</Style>
<Style x:Key="buttonStyle" TargetType="Button" BasedOn="{StaticResource baseStyle}">
<Setter Property="FontSize" Value="Large" />
<Setter Property="TextColor" Value="Red" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="0,20,0,0">
<SearchBar Placeholder="These SearchBar controls" Style="{DynamicResource searchBarStyle}" />
<SearchBar Placeholder="are demonstrating" Style="{DynamicResource searchBarStyle}" />
<SearchBar Placeholder="dynamic styles," Style="{DynamicResource searchBarStyle}" />
<SearchBar Placeholder="but this isn't dynamic" Style="{StaticResource blueSearchBarStyle}" />
<Button Text="Change Style" Style="{StaticResource buttonStyle}" Clicked="OnButtonClicked" />
</StackLayout>
</ContentPage.Content>
The xaml.cs code is :
public partial class DynamicStylesPage : ContentPage
{
bool originalStyle = true;
public DynamicStylesPage ()
{
InitializeComponent ();
Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];
}
void OnButtonClicked (object sender, EventArgs e)
{
if (originalStyle) {
Resources ["searchBarStyle"] = Resources ["greenSearchBarStyle"];
originalStyle = false;
} else {
Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];
originalStyle = true;
}
}
}
For more details,please check document Dynamic Styles in Xamarin.Forms.
And there is a sample included in above ducument, you can check it here:https://learn.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/userinterface-styles-dynamicstyles/
Related
I have a data grid in my WPF project and this my Xaml and c# codes, why can't I change its foreground for column header style and element style? does anybody know where is wrong with my code? I have several data grid in my project and I use the same codes for all of them without any change but in some data grids it works for both column header style and element style or just for column header style either column element style only and in the rest it doesn't work for any of them.
<Window.Resources>
<SolidColorBrush x:Key="DgColumnHeaderForeground" Color="Black"/>
<SolidColorBrush x:Key="DgColumnElementForeground" Color="Black"/>
</Window.Resources>
<Grid>
<DataGrid x:Name="DgSuggestion" AutoGenerateColumns="False" FlowDirection="RightToLeft" HorizontalAlignment="Left"
Height="326" Margin="10,158,0,0" VerticalAlignment="Top" Width="662" IsReadOnly="True">
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#7FEEE30E" />
</DataGrid.Resources>
<DataGrid.VerticalGridLinesBrush>
<SolidColorBrush Color="#FFBDB0B0" Opacity="0.7" />
</DataGrid.VerticalGridLinesBrush>
<DataGrid.HorizontalGridLinesBrush>
<SolidColorBrush Color="#FFBDB0B0" Opacity="0.7" />
</DataGrid.HorizontalGridLinesBrush>
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding SuggestionID}" FontSize="14" FontFamily="Calibri" MaxWidth="0" />
<DataGridTextColumn Header="Date" Binding="{Binding SuggestionRequestDate, StringFormat=\{0:dd.MM.yyyy\}}" Width="Auto">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="{DynamicResource DgColumnHeaderForeground}" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Foreground" Value="{DynamicResource DgColumnElementForeground}" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Dept" Binding="{Binding SuggestionDept}" Width="Auto">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="{DynamicResource DgColumnHeaderForeground}" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Foreground" Value="{DynamicResource DgColumnElementForeground}" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
And this is my code behind
private void WinAppearanceMethod()
{
var brush5 = FindResource("DgColumnElementForeground") as SolidColorBrush;
if (brush5.IsFrozen) brush5 = brush5.Clone();
if (!string.IsNullOrEmpty(Default.dgContentFontColor)) brush5.Color = (Color)ColorConverter.ConvertFromString(Default.dgContentFontColor);
var brush6 = FindResource("DgColumnHeaderForeground") as SolidColorBrush;
if (brush6.IsFrozen) brush6 = brush6.Clone();
if (!string.IsNullOrEmpty(Default.dgHeaderFontColor)) brush6.Color = (Color)ColorConverter.ConvertFromString(Default.dgHeaderFontColor);
}
As I can see the behavior you described have several factors which can impact the color of the header/element.
Using the brush in some elements do freeze the brush, e.g. adding somewhere TextBlock with a Foreground set to "{DynamicResource DgColumnElementForeground}" or "{DynamicResource DgColumnHeaderForeground}" will make brush frozen. Also using the brush by the elements of DataGrid.
In case you modify DgColumnElementForeground before the grid is filled you will see the change.
Error in your code, that having a frozen object you make a clone, modify it, but doesn't set it back to the resource dictionary.
private void WinAppearanceMethod()
{
var brush5 = FindResource("DgColumnElementForeground") as SolidColorBrush;
if(brush5.IsFrozen)
brush5 = brush5.Clone();
if(!string.IsNullOrEmpty(Default.dgContentFontColor))
{
brush5.Color = (Color)ColorConverter.ConvertFromString(Default.dgContentFontColor);
Resources["DgColumnElementForeground"] = brush5;
}
var brush6 = FindResource("DgColumnHeaderForeground") as SolidColorBrush;
if(brush6.IsFrozen)
brush6 = brush6.Clone();
if(!string.IsNullOrEmpty(Default.dgHeaderFontColor))
{
brush6.Color = (Color)ColorConverter.ConvertFromString(Default.dgHeaderFontColor);
Resources["DgColumnHeaderForeground"] = brush6;
}
}
I want to apply a default style for all the Buttons in a WPF app. This test app has two Windows, both defining the same UI showing bellow.
<StackPanel Orientation="Vertical" Margin="10">
<Button Content="Red Button Style" />
<Button Content="Red Button Style" />
<Button Content="Red Button Style" />
<Button Content="Red Button Style" />
</StackPanel>
So I've defined the global style in App.xaml
<Application x:Class="GlobalStyles.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GlobalStyles">
<Application.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Height"
Value="30" />
<Setter Property="MinWidth"
Value="180" />
<Setter Property="FontSize"
Value="16" />
<Setter Property="HorizontalAlignment"
Value="Center" />
<Setter Property="Padding"
Value="8 0" />
<Setter Property="Margin"
Value="4" />
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="BorderThickness"
Value="2" />
<Setter Property="BorderBrush"
Value="DarkRed" />
<Setter Property="Foreground"
Value="White" />
<Setter Property="Background"
Value="OrangeRed" />
</Style>
</Application.Resources>
</Application>
and as you've noticed I removed the StartupUri property of Application since I'm creating both windows at OnStartUp().
App.xaml.cs
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
new MainWindow().Show();
new SecondaryWindow().Show();
}
The Problem
The styles are not applying at runtime (but they do on the designer). Now if I place the StartUpUri property inside App.xaml then it works.
What's the deal here?
Edit
If the base.OnStartup(e) call is removed from OnStartup(), then it works.
You can create your windows in the Startup handler.
private void App_OnStartup(object sender, StartupEventArgs e)
{
new MainWindow().Show();
new SecondaryWindow().Show();
}
I have a default Label Style
<Style x:Key="LabelStyle" TargetType="{x:Type Label}">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="13.333" />
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
<Style BasedOn="{StaticResource LabelStyle}" TargetType="{x:Type Label}" />
I then try to use a different style for a single Label
<Style x:Key="HeaderLabelStyle" TargetType="{x:Type Label}">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Foreground" Value="{StaticResource HeaderForegroundBrush}" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
<Label Content="Text here" Name="someName" Style="{StaticResource HeaderLabelStyle}"/>
But for some reason the label always gets the default style. Why? Can this be overridden?
Thanks
So I realised that the default (string) template for Label is an indented TextBlock (styles are inherited)
Since I also was defining a global style for TextBlock
<Style x:Key="TextBlockStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
<Setter Property="FontSize" Value="13.333" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Style BasedOn="{StaticResource TextBlockStyle}" TargetType="{x:Type TextBlock}" />
No matter how many types of Label I had I was always bound to use the template for TextBlock
So the solution was to define a dummy TextBlock class
namespace Theme
{
public class HeaderTextBlock : TextBlock
{
}
}
Then assign it its own global style
xmlns:this="clr-namespace:Theme"
<Style x:Key="HeaderTextBlockStyle" TargetType="this:HeaderTextBlock">
<Setter Property="Foreground" Value="{StaticResource HeaderForegroundBrush}" />
<Setter Property="FontSize" Value="13.333" />
<Setter Property="FontFamily" Value="Segoe UI" />
</Style>
<Style BasedOn="{StaticResource HeaderTextBlockStyle}" TargetType="{x:Type this:HeaderTextBlock}" />
And use TextBlocks instead of Labels (haven't figured out how to implement a Label child yet since (Label : TextBlock) = false
xmlns:theme="clr-namespace:Theme;assembly=Theme"
<theme:HeaderTextBlock Text="Some text" Name="titleLabel" Style="{StaticResource HeaderTextBlockStyle}"/>
This is my Xaml:
<Style TargetType="ComboBox">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="5" />
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="White" />
</Style>
<Style TargetType="TextBox">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Margin" Value="5" />
<Setter Property="Height" Value="35" />
<Setter Property="FontSize" Value="20" />
</Style>
[...]
<ComboBox SelectedIndex="{Binding Path=BirthdayDay, UpdateSourceTrigger=PropertyChanged, FallbackValue=0}" ItemsSource="{Binding Path=Days, UpdateSourceTrigger=PropertyChanged}" />
<ComboBox SelectedIndex="{Binding Path=BirthdayMonth, UpdateSourceTrigger=PropertyChanged, FallbackValue=0}" ItemsSource="{Binding Path=Months, UpdateSourceTrigger=PropertyChanged}" />
<ComboBox SelectedIndex="{Binding Path=BirthdayYear, UpdateSourceTrigger=PropertyChanged, FallbackValue=0}" ItemsSource="{Binding Path=Years, UpdateSourceTrigger=PropertyChanged}" />
And the result is very confusing:
Is it somehow colliding with the TextBlock Style?
Since the FontWeight is applied it seems like there is a connection ?!
NOTE:
The only "obvious" difference I can see it that the Binding differs:
Day + Year is a Collection of Integers while Month is a Collection of string?!
This is due to the type of the data and the fact that you didn't define a way to display the data : ItemTemplate, ItemTemplateSelector or StringFormat
If you add <Setter Property="ItemStringFormat" Value="{}{0}"></Setter>
All ComboBoxes will display correctly.
The ItemsControl.UpdateSelectionBoxItem is the function that is in charge of displaying data in the selection box but I couldn't figure how it treated int differently from String in the process of extracting and displaying the Item.
Anyway, int are displayed as TextBlocks and String as TextBox if I get it right, and that's why you int takes your Style.
Maybe you could try something like this:
<Window.Resources>
<Style x:Key="CommonStyle" TargetType="FrameworkElement">
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="ComboBox" BasedOn="{StaticResource CommonStyle}">
</Style>
</Window.Resources>
I want to create a template for a XAML WPF application.
I have two problems:
1) I have to set positione TabItem Header on top right of UserControl
2) I set TabItem Style, but when ouse go over tabItem Header, i see default Item effetcs on text.
<TabControl>
<TabItem Header="{DynamicResource tab_header_graphic_interface}" Style="{StaticResource generalTabItem}">
<ScrollViewer CanContentScroll="True" VerticalScrollBarVisibility="Auto" Name="scrDrvPan">
</ScrollViewer>
</TabItem>
<TabItem Header="{DynamicResource tab_header_list_view}" Style="{StaticResource generalTabItem}">
<ScrollViewer CanContentScroll="True" VerticalScrollBarVisibility="Auto" Name="scrDrvList">
</ScrollViewer>
</TabItem>
</TabControl>
And i set style for TabItem
<Grid.Resources>
<Style x:Key="generalTabItem" TargetType="{x:Type TabItem}">
<Setter Property="FontFamily" Value="/Font/#Futura Std Medium" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Foreground" Value="#FF333333" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0 0 0 0" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Height" Value="30" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<!--<DockPanel IsItemsHost="True" LastChildFill="False" Margin="2,2,2,0" HorizontalAlignment="Right">
</DockPanel>-->
<!--<ContentPresenter Content="{TemplateBinding Property=TabItem.Header}"/>-->
<TextBlock Background="Transparent" Text="ciao" />
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="TabItem.IsSelected" Value="True">
<Setter Property="FontFamily" Value="/Font/#Futura Std Bold" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Foreground" Value="#FF333333" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0 0 0 0" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Height" Value="30" />
</Trigger>
<Trigger Property="TabItem.IsFocused" Value="True">
<Setter Property="FontFamily" Value="/Font/#Futura Std Bold" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Foreground" Value="#FF333333" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0 0 0 0" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Height" Value="30" />
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
Have you tried this in your HeaderTemplate DataTemplate?`
<TextBlock Background="Transparent" Text="{Binding}" HorizontalAlignment="Right" VerticalAlignment="Top" />