Why style is not applied when I'm removing StartupUri in WPF? - c#

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();
}

Related

Is there a way to change the style basedon property programmatically?

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/

app.xaml resources won't work. dot.net core stuff?

I had the following resources defined in the app.xaml file, that worked perfectly:
<Application.Resources>
<Style TargetType="Button" x:Key="homeButtom">
<Setter Property="Margin" Value="5" />
<Setter Property="Padding" Value="4" />
<Setter Property="Width" Value="110" />
<Setter Property="Background" Value="CadetBlue" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="14" />
</Style>
</Application.Resources>
Then, I added entity framework to the solution and, as recommended, O removed the "StartupUri="MainWindow.xaml" from the header and inserted the call in the code behind:
protected override async void OnStartup(StartupEventArgs e)
{
await host.StartAsync();
var mainWindow = host.Services.GetRequiredService<MainWindow>();
mainWindow.Show();
base.OnStartup(e);
}
And the resources won't work unless it's set on the pages it's needed.
Just adding, that I guess that's the reason. The fact is that my resources just work from app.xaml...
I can confirm that the way you have presented the resource, it doesn't work in dot net core. However, I found that if you place your resource inside of a ResourceDictionary, it will work.
App.xaml.cs:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MyResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
MyResourceDictionary.xaml:
<Style TargetType="Button" x:Key="homeButtom">
<Setter Property="Margin" Value="5" />
<Setter Property="Padding" Value="4" />
<Setter Property="Width" Value="110" />
<Setter Property="Background" Value="CadetBlue" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="14" />
</Style>

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

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>

Style a window in visual studio

My issue it that I have created a text box that bolds when someone clicks into it. I want it to unbold when I click somewhere else on the screen. Now heres that hard part I need to do that in my style sheets and the .cs sheet hooked up to style sheet. The contents of my .cs sheet is
using System.Windows;
using System.Windows.Input;
namespace SimTechGUI
{
public partial class MyResourceDictionary : ResourceDictionary
{
public MyResourceDictionary()
{
InitializeComponent();
}
private void Window_Focus(object sender, MouseButtonEventArgs e)
{
Keyboard.ClearFocus();
}
}
}
My xaml style sheet looks like
<ResourceDictionary xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SimTechGUI.MyResourceDictionary"
x:ClassModifier="public">
<Style TargetType="{x:Type Window}">
<EventSetter Event="MouseDown" Handler="Window_Focus" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="25" />
<Setter Property="AllowDrop" Value="true" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border Name="Border" CornerRadius="6" Padding="2" BorderBrush="Black" BorderThickness="2,1">
<ScrollViewer Margin="0" x:Name="PART_ContentHost" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="BorderThickness" TargetName="Border" Value="3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
What I have does not currently work. Does anyone know what I have to do to make this work.
Your code works fine if you set MouseDown Event Handler directly on Window
MouseDown="Window_Focus"
The way you have the style applied, the Window_Focus Handler never hits. Put a breakpoint on Keyboard.ClearFocus(); and see if it hits?
You can Apply the Style by Name Explicitly
Define a style like this:
<Style x:Key="windowStyle" TargetType="Window">
<EventSetter Event="MouseDown" Handler="Window_Focus" />
</Style>
and Apply like this to all the Windows:
Style="{StaticResource windowStyle}"
The reason I think it's not letting you specify Style Implicitly is probably there is an Style already being applied to all the Windows:
Look at these posts:
What reasons could prevent explicit and implicit styles from applying?
or
Global Style not working in WPF

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