I am trying to make an App with Xamarin.Android where I have a RadioGroup with all my themes. I am trying to change the theme when the certain RadioButton from the group is checked, but it doesn't seem to work. Any ideas why?
styles.xml
<resources>
<style name="LightTheme" parent="android:Theme.Material.Light.DarkActionBar">
<item name="android:colorPrimary"> #color/blue</item>
<item name="android:windowBackground"> #color/grey</item>
<item name="android:colorAccent"> #color/yellow </item>
</style>
<style name="DarkTheme" parent="android:Theme.Material.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:colorPrimary"> #color/green </item>
<item name="android:colorPrimaryDark"> #color/blue </item>
<item name="android:colorAccent"> #color/purple </item>
<item name="android:windowBackground"> #color/dark_blue </item>
</style>
</resources>
layout.axml
<RadioGroup
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/errorMsg"
android:onClick ="Change"
android:id="#+id/radGrp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="Dark"
android:id="#+id/radDark" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Light"
android:id="#+id/radLight" />
</RadioGroup>
MainActivity.cs
RadioGroup radGrp = FindViewById<RadioGroup>(Resource.Id.radGrp);
radGrp.CheckedChange += Change;
private void Change(object sender, RadioGroup.CheckedChangeEventArgs e)
{
try
{
switch (e.CheckedId)
{
case Resource.Id.radDark: this.SetTheme(Resource.Style.DarkTheme); break;
case Resource.Id.radLight: this.SetTheme(Resource.Style.LightTheme); break;
}
}
catch (Exception ex)
{
errMsg.Text = ex.Message;
}
}
Do I need to change something in AndroidManifest.xaml or in the [Activity(Label = "#string/app_name", Theme=... , MainLauncher = true)] ?
This is a limitation/feature of the way Themeing is implemented on Android. Changing an Activity's Theme doesn't actually take effect until the Activity runs OnResume, so effectively you have to re-start the activity. There are various strategies you can use to minimize the impact on the user. Xamarin actually provides a sample Theme Switcher app which might be a good reference for implementing something: https://developer.xamarin.com/samples/monodroid/android5.0/ThemeSwitcher/
Themes and Styling
Styling is the mechanism whereby the values assigned to properties/attributes are defined externally and then assigned to an object, which then applies them. This allows a single style definition to be applied to multiple objects, rather than having to define each property value for each object individually.
The use of styling ensures consistency in design within and across applications, reduces errors, and can save significant effort. It allows developers to quickly apply the overall visual design and concentrate on developing the value-added aspects of the application.
The styling system in Android is so tightly coupled into the Android ecosystem, that some things are impractical to achieve by any other mechanism, read some things you can’t do in code, only using the styling system :-(
An Android style is an xml file that defines a set of property/attribute values. It can be targeted to a single class or multiple classes. Because it conforms to the xml standard, tags that are not relevant to an object are ignored by that object when applied to it.
Styling in Android can be applied at an application, activity, or object level.
From a technical perspective Themes and Styles are interchangeable. A Theme is just a Style applied at the Application or Activity level. The following should be used when referring to them:
Style: Defines a set of properties/attributes applied at the class
and/or object level.
Theme: Defines a set of properties/attributes
applied at the Application or Activity level.
Typically a Style used as a Theme will contain definitions for properties/attributes for many classes.
Styles (and therefore Themes) exhibit inheritance. A Style can inherit from another style, and then add and/or modify property/attribute values.
Styles (and the properties/attributes they define) are also applied hierarchically. In Android, the order of precedence is:
Property/attribute applied directly to an object > overrides > setting a property/attribute by applying a Style to an object > overrides > setting a property by applying a Theme (Style) to an Activity > overrides > setting a property by applying a Theme (Style) to an Application.
Android provides a number of predefined Styles for use as Themes. You can apply these as is or create your own Themes bases on them via inheritance. To support this, the Android styling system defines some styling attributes that these themes use and automatically apply across multiple objects. These includes things like colorPrimary, colorAccent, colorControlNormal, colorControlActivated, textColorSecondary etc. You can re-assign values to these in Styles so the new values are applied. You can also reference them in Styles, so you can pick up the values assigned to them in your applied Theme.
Lastly, different versions of Android may apply styling slightly differently (often due to changes in the properties/attributes of the objects), especially any styling system attributes. This is especially obvious between versions 4.4- and 5.0+ when Material Design was adopted. The support libraries address some of these inconsistencies, and each release of them seems to get slightly better, but if you need to support 4.4 and below, you will almost definitely find your self having to define some styles in both the values and the vales-v21 folders so they are applied appropriately to the different versions.
Related
Want to do
I want to make checkbox with 4 patterns.
To achieve this, I want to know,
① How to change the color of check.
② How to change the color of frame border of checkbox.
I already tried this code and changed the background's color. However it doesn't work enough to achieve what I want.
//change the color of background in a checkbox
android:buttonTint="#ffffff"
In general, you can use property android:button to achieve this.
Please refer to the following code:
1.create a xml file checkbox_background.xml in folder drawable
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="#drawable/checked" />
<item android:state_checked="false"
android:drawable="#drawable/unchecked" />
</selector>
2.set the android:button property of CheckBox to checkbox_background:
<CheckBox
android:id="#+id/check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#drawable/checkbox_background" />
Note: You can also set other status of checkbox in the item of selector .
You need to manually define various attributes in xml.
Here is an example - you need to modify it to your specific use case:
<CheckBox
android:layout_width="60dp"
android:layout_height="60dp"
android:button="#null"
android:id="#+id/checkbox"
android:background="?android:attr/listChoiceIndicatorMultiple"
android:colorAccent="#color/checkboxcolor"
android:buttonTint="#color/checkboxcolor" />
You can of course change the android:background to something else.
Also notice the android:button can be any drawable, but I am not using it and then set it to #null. So you should be able to achieve your desired result by working with these xml attributes such as the background (any drawable - here I am just using a built in drawable from android, but you can use your own drawable. You can then have a border defined inside that custom drawable if you want.
When a named XAML element is used in a WPF application, it can be accessed from anywhere. For example:
<Grid>
<Grid>
<TreeViewItem Name="itemScreen" />
The element itemScreen will be directly accessible in MainWindow(), although it is several levels deep in the XAML hierarchy.
How does WPF enable this to work in C#?
There's a mechanism called NameScope.
https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/wpf-xaml-namescopes
Simple markup you put in a window which has no templating or styling will all have the one namescope.
If you dig through that link it will explain about styles and templates in more detail. Essentially, they have their own namescope.
This is probably as far as you want to go with an explanation at this stage but there are a couple of oddities like when you "inherit" a style using basedon.
I wouldn't worry about them just yet but throw it to the back of your mind for later.
ps
That control is a private member of your window and the name doesn't have to be unique across the entire application.
As an example, I would like to apply the ButtonRevealStyle to my button:
<Button Style="{StaticResource ButtonRevealStyle}" Grid.Column="1" Width="38" ... />
This will work, but of course only on a device with the Fall Creators Update installed. How do I disable this for all previous versions of W10?
I know I can use .IsApiPresent() in the code-behind when I want to check for a specific Windows Api but in this case this doesn't seem to be the preferred/recommended solution and I'd like to stick to just XAML for this. Doing it in C# requires referencing every single control with that style in code-behind and manually assigning the style if it's present. I'm pretty sure this is not the best solution in this day and age, where you can set up responsive and animated layouts solely in XAML. Besides, if the button was in a ListView.ItemTemplate just accessing each control would require a few solid lines of code. Not to mention the check itself
Is it possible? Am I missing something?
Edit: Turns out it is possible, and I totally was missing something. Conditional XAML can easily be done and isn't that complex all things considered. It's just a matter of setting a custom namespace in the file (pointing to the same resource as the 'root' namespace, just with the `IsApiContractPresent" check at the end. Yes, it is possible to use that in XAML.
After setting the custom namespace you can then specify attributes that will only be aplied when the certain API is present on the End-User's device. Example:
xmlns:fcu="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
...
<Button fcu:Style="{StaticResource ButtonRevealStyle}" Grid.Column="1" Width="38" ... />
This will result in the button getting Reveal only on PCs with Fall Creators Update and the previous versions won't be throwing an error.
More info: https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/conditional-xaml
You people clearly like your downvote button a bit too much.
Turns out it is possible, and I totally was missing something. Conditional XAML can easily be done and isn't that complex all things considered. It's just a matter of setting a custom namespace in the file (pointing to the same resource as the 'root' namespace, just with the `IsApiContractPresent" check at the end. Yes, it is possible to use that in XAML.
After setting the custom namespace you can then specify attributes that will only be aplied when the certain API is present on the End-User's device. Example:
xmlns:fcu="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
...
<Button fcu:Style="{StaticResource ButtonRevealStyle}" Grid.Column="1" Width="38" ... />
This will result in the button getting Reveal only on PCs with Fall Creators Update and the previous versions won't be throwing an error.
More info: https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/conditional-xaml
I have a few user controls that need to be shared between multiple Silverlight 4 project. I am creating a new project that defines those controls in a namespace called [appname].[UI]
I want to create a new Stylesheet for all these controls within the project, however I don't know how to reference the styles at design time (I can reference them via the style="" attribute, but they never get applied).
More over I do know that the application has to "Register" the style sheet as part of its resources. Is there a way to do so from within my UI project?
Am I wrong with my assumptions or is there any work around these issues?
To register, add the <MergedDictionary> tag in your App.xaml <ResourceDictionary> entry. This will allow the application to access your styles, like so:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="YourResourceFile.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Once they are registered, the Style="" attribute should work, but if it doesn't, post the code. It might be an error in the XAML.
The silverlight terminology surrounding styles is a bit confusing. It sounds like when you say stylesheet that you really mean templates. If you want to consistently set public properties on controls (eg. FontSize, Background, etc), you'll want to use a style. But if you want to change the way the control is laid out you're going to want to set a new control template. Modifying the control template is much more powerful for customizing controls but also can be a pain because as far as I know you can only edit templates via the XAML. I think you might be able edit the templates WYSIWYG if you're using Expression Blend.
Overview of differences between Styles and Templates:
http://msdn.microsoft.com/en-us/library/cc295273.aspx
Soon to be a professional .NET developer (I hope) I start to dig into Windows Presentation Foundation (WPF). Looking into several video tutorials, I find design of GUI a daunting task. Having to specify every color, on every element, in every situation, to every platform seems a bit too much. How can you make this process simpler, and more generic when it comes to design? Is there any templates to start from, or is one expected to specify a couple of hundred rows of XAML before the design is looking appealing?
Considering the code-block below...
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="LightGreen" />
<Setter Property="Foreground" Value="DarkGreen" />
</Style>
... where properties for hover and pushed-button style is left out which need additional rows of XAML to do what the developer wants.
Might there be a simple XAML-editor around to increase productivity? If there isn't, its just to dig dip into XAML and start building styles too keep for later projects.
Designing your own theme is great but it requires a lot of expertise and time. From my point of view its not a great idea to invest in designing your own theme, provided you already have so many themes availabe online. You can take one which suits you and modify it as per your needs.
I genrally refer these links for themes -
WPF Themes -
http://wpfthemes.codeplex.com/
http://wpf.codeplex.com/wikipage?title=WPF%20Themes&ProjectName=wpf
WPF Theme Selector
http://wpfthemeselector.codeplex.com/
Wpf Project With 21 Theme
https://marketplace.visualstudio.com/items?itemName=AliAlikhani.SahaWpfTheme2012
In case you need more options you can buy one here -
http://www.xamltemplates.net/wpf-themes/
There is no requirement to create a Style. You can just use the default style. Consider this simple messagebox style window:
<Window x:Class="MyProject.Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Height="217" Width="298">
<StackPanel Orientation="Vertical">
<Label>Here is the Message.</Label>
<StackPanel Orientation="Horizontal">
<Button>OK</Button>
<Button>Cancel</Button>
</StackPanel>
</StackPanel>
</Window>
If you really need to re-style controls, I would pick and choose which ones to do. Otherwise, yes I think creating a custom style is a pretty big task.
Creating a custom style is a very large task, however, should you decide this is neccesary (it's not required). You can use Expression Blend to speed up the process.
Reuxables have a couple of free themes you can try. We've just bought one of their non-free ones and it's dead easy, you just throw in a reference in your app.xaml and it transforms your app. Easy to tailor, too.