Is it possible to scale a control in a VisualState - xaml

Using MinWindowWidth in an AdaptiveTrigger I am able change the background color but I am unable to apply a scale transform.
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="hsCards.(Control.Background)">
<Setter.Value>
<SolidColorBrush Color="Green"/>
</Setter.Value>
</Setter>
<Setter Target="hubFlashCards.(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Value="0.8"/>
<Setter Target="hubFlashCards.(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Value="0.8"/>
</VisualState.Setters>
</VisualState>
Not only does the scaling not work but the background Setter does not either. If I remove the scale transform the background Setter works fine.
Am I doing something wrong or is it not possible to use the RenderTransform in this way?

In this case I would assign x:Name straight to the CompositeTrasform element. And then the Visual state:
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0">
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="hsCards.Background">
<Setter.Value>
<SolidColorBrush Color="Green"/>
</Setter.Value>
</Setter>
<Setter Target="yourComposite1.ScaleX" Value="0.8"/>
<Setter Target="yourComposite1.ScaleY" Value="0.8"/>
</VisualState.Setters>
</VisualState>
I may not be exactly like your solution, but it's the way I use since I started with UWP.

Related

Styling depending on screen orientation in Xamarin forms

I am styling on phone and tablet but how can I add the option also for orientation? this is all for portrait but how can I add option for horizontal orientation?
<Style TargetType="Grid" x:Key="DocType">
<Setter Property="HeightRequest">
<Setter.Value>
<OnIdiom Phone="50" Tablet="80" />
</Setter.Value>
</Setter>
<Setter Property="BackgroundColor" Value="#F4F5F7"/>
</Style>
You can use OrientationStateTrigger with VisualStateManager here is an example:
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState
x:Name="Landscape">
<VisualState.StateTriggers>
<OrientationStateTrigger Orientation="Landscape" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Blue" />
</VisualState.Setters>
</VisualState>
<VisualState
x:Name="Portrait">
<VisualState.StateTriggers>
<OrientationStateTrigger Orientation="Portrait" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
Source
EDIT
VisualStateManager inside a style, combined with OnIdiom
<Style TargetType="Grid" x:Key="DocType">
<Setter Property="HeightRequest">
<Setter.Value>
<OnIdiom Phone="50" Tablet="80" />
</Setter.Value>
</Setter>
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState x:Name="Landscape">
<VisualState.StateTriggers>
<OrientationStateTrigger Orientation="Landscape" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor">
<Setter.Value>
<OnIdiom Phone="Blue" Tablet="Green" />
</Setter.Value>
</Setter>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Portrait">
<VisualState.StateTriggers>
<OrientationStateTrigger Orientation="Portrait" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Property="BackgroundColor">
<Setter.Value>
<OnIdiom Phone="Yellow" Tablet="Purple" />
</Setter.Value>
</Setter>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
in this example:
Mode
Tablet
Phone
Landscape
Green
Blue
Portrait
Purple
Yellow

Rider Xamarin xaml: "Field Normal is already declared" from VisualStateManager

I'm using Xamarin Forms 4.5.0.617 and want to use a VisualStateManager (https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/visual-state-manager) to change the style if an element is disabled. To apply this to all my styles, I have to use the x:Name="Normal" or "Disabled" or "Focused" multiple times, but Rider (https://www.jetbrains.com/de-de/rider/) says error
The app runs correctly (style is changing) but the warning of rider is still annoying.
Am I doing something wrong?
<?xml version="1.0" encoding="utf-8"?>
<Application
x:Class="ProjectApp.App"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:components="clr-namespace:Project.Components"
xmlns:converters="clr-namespace:Project.Converters"
xmlns:helpers="clr-namespace:Project.Helpers"
xmlns:iconize="clr-namespace:Plugin.Iconize;assembly=Plugin.Iconize">
<Application.Resources>
<ResourceDictionary>
<!-- Text -->
<Style
x:Key="Label"
TargetType="Label">
<Setter
Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState
x:Name="Normal">
<VisualState.Setters>
<Setter
Property="TextColor"
Value="Black" />
</VisualState.Setters>
</VisualState>
<VisualState
x:Name="Disabled">
<VisualState.Setters>
<Setter
Property="TextColor"
Value="Gray" />
</VisualState.Setters>
</VisualState>
<VisualState
x:Name="Focused">
<VisualState.Setters>
<Setter
Property="TextColor"
Value="{StaticResource Primary}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<!-- Picker -->
<Style
x:Key="Picker"
TargetType="Picker">
<Setter
Property="FontSize"
Value="14" />
<Setter
Property="TextColor"
Value="Black" />
<Setter
Property="VerticalOptions"
Value="Center" />
<Setter
Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState
x:Name="Normal">
<VisualState.Setters>
<Setter
Property="TextColor"
Value="Black" />
</VisualState.Setters>
</VisualState>
<VisualState
x:Name="Disabled">
<VisualState.Setters>
<Setter
Property="TextColor"
Value="Gray" />
</VisualState.Setters>
</VisualState>
<VisualState
x:Name="Focused">
<VisualState.Setters>
<Setter
Property="TextColor"
Value="{StaticResource Primary}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
You are not doing anything wrong. This is a confirmed known issue with Rider/ReSharper. I have already reported it here.
What I can suggest is that you upvote the issue and/or write a comment, so that they can escalate it and fix it quickly.

How can I change the font and font size of a gridview as focus/selection changes

In UWP I'm building a Gridview that contains letters. (e.g. A B C D E F G... Z) as the user navigates in the Gridview I'd like to change the font(and size) of the currently selected/focused letter. I'd like to be able to do it via XAML if possible but I can't seem to make it work.
Some background:
I've created a DataTemplate to represent my letters (I have 2 data templates, one for enabled letters and one for disabled letters) and I use an ItemTemplateSelector and databinding to render the list of letters.
I've a LetterModel that represents the Letter and it's state so that At page load some the disabled letters have a different look and those items are disabled in the gridview. I'd now like to be able to change the font and font size via the styling of the LIstViewPresenter (if this is even possible).
Some code:
Letter Model:
public class LetterModel
{
public string Letter { get; set; }
public bool IsEnabled { get; set; }
}
Data Templates XAML (contained in a resource file along with the GridViewItem Style overrides I've implemented):
<helpers:LetterSelector x:Key="alphabetSelector" EnabledTemplate="{StaticResource LetterEnabled}" DisabledTemplate="{StaticResource LetterEnabled}"/>
<DataTemplate x:Name="LetterEnabled">
<TextBlock x:Name="myLetter" Text="{Binding Letter}" Style="{StaticResource LetterTextStyle}" FontSize="24"/>
</DataTemplate>
<DataTemplate x:Name="LetterDisabled">
<TextBlock x:Name="myLetter" Text="{Binding Letter}" Style="{StaticResource DisabledLetterTextStyle}" Foreground="{StaticResource MyColor}" FontSize="24"/>
</DataTemplate>
Declaration of GridView in a page:
<GridView x:Name="alphaGrid" Width="Auto" Height="Auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Margin="22, 0, 22, 0"
SelectionChanged="AlphaGrid_SelectionChanged"
ItemsSource="{x:Bind MyViewModel.Letters}"
ItemTemplateSelector="{StaticResource alphabetSelector}"
ItemContainerStyle="{StaticResource LetterSelectionGridViewStyle}">
Here is my LetterSelectionGridViewStyle:
<Style x:Key="LetterSelectionGridViewStyle" TargetType="GridViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="Background" Value="{ThemeResource GridViewItemBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource GridViewItemForeground}"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,0,6,6"/>
<Setter Property="MinWidth" Value="{ThemeResource GridViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource GridViewItemMinHeight}"/>
<Setter Property="AllowDrop" Value="False"/>
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
<Setter Property="FocusVisualMargin" Value="-2,-2,-2,-6"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewItem">
<ListViewItemPresenter x:Name="Root" CheckBrush="{ThemeResource GridViewItemCheckBrush}"
ContentMargin="{TemplateBinding Padding}"
CheckBoxBrush="{ThemeResource GridViewItemCheckBoxBrush}"
ContentTransitions="{TemplateBinding ContentTransitions}"
CheckMode="{ThemeResource GridViewItemCheckMode}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
DragBackground="{ThemeResource GridViewItemDragBackground}"
DragForeground="{ThemeResource GridViewItemDragForeground}"
FocusBorderBrush="{ThemeResource GridViewItemFocusBorderBrush}"
FocusVisualPrimaryBrush="{StaticResource MyOrange}"
FocusVisualPrimaryThickness="0,0,0,8"
FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
FocusSecondaryBorderBrush="{ThemeResource GridViewItemFocusSecondaryBorderBrush}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Control.IsTemplateFocusTarget="True"
PressedBackground="{ThemeResource GridViewItemBackgroundPressed}"
PlaceholderBackground="{ThemeResource GridViewItemPlaceholderBackground}"
PointerOverForeground="{ThemeResource GridViewItemForegroundPointerOver}"
PointerOverBackground="{ThemeResource GridViewItemBackgroundPointerOver}"
RevealBorderThickness="{ThemeResource GridViewItemRevealBorderThemeThickness}"
ReorderHintOffset="{ThemeResource GridViewItemReorderHintThemeOffset}"
RevealBorderBrush="{ThemeResource GridViewItemRevealBorderBrush}"
RevealBackground="{ThemeResource GridViewItemRevealBackground}"
SelectedForeground="{ThemeResource GridViewItemForegroundSelected}"
SelectionCheckMarkVisualEnabled="{ThemeResource GridViewItemSelectionCheckMarkVisualEnabled}"
SelectedBackground="{ThemeResource SystemControlTransparentBrush}"
SelectedPressedBackground="{ThemeResource SystemControlTransparentBrush}"
SelectedPointerOverBackground="{ThemeResource SystemControlTransparentBrush}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Selected"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverPressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled"/>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Ideally I'd be able to do something in the VisualStateGroups that understands the selected/unselected behavior and I could change the FontSize Properties in my datatemplate
Or am I just misunderstanding something here?
I tried using behaviors in my DataTemplate however that changed all the letter's fonts... not just the selected.
I've spent a lot of time trying to Understand if this should be doable in XAML.
Thanks!
If you set the FontSize=24 in your DataTemplate, then the font size applied to 'ListViewItemPresenter' will not work.
So, if you want to change the font size when the GridViewItem is selected in visual state, you need to remove the FontSize=24 in your DataTemplate and change the font size in 'Selected' visual state directly.
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Target="Root.FontSize" Value="50"></Setter>
</VisualState.Setters>
</VisualState>

UWP Change Grid.HorizontalAlignment to stretch/left using VisualStateManager

I'm having trouble getting the visual state manager to correctly change the HorizontalAlignment/VerticleAlignment of the main grid of my application.
For screen sizes that would be used on phone, I want the HorizontalAlignment/ VerticleAlignment to stretch, with Height/Width set to Auto.
For Desktop it should be Left/Top with Height/Width set to a specific size. For whatever reason when I try to mess with the alignment it acts quirky and does not do what I want
Here is an example of what I have tried:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="PhoneView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Grid.HorizontalAlignment" Value="Stretch"/>
<Setter Target="Grid.VerticleAlignment" Value="Stretch"/>
<Setter Target="Grid.Height" Value="Auto"/>
<Setter Target="Grid.Width" Value="Auto"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="DesktopSmall">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1920"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Grid.HorizontalAlignment" Value="Left"/>
<Setter Target="Grid.VerticleAlignment" Value="Top"/>
<Setter Target="Grid.Height" Value="1280"/>
<Setter Target="Grid.Width" Value="1920"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
Another issue is when I try to set the max resolution to 1920x1280, if I manually set the height/width of the Grid, the Windows TaskBar (the OS taskbar, not the applications app bar/command bar) cuts off part of my application. I don't want to set the alignments to stretch, because I'm trying to limit the real time stretching of the view.
Thanks! Let me know if more details are needed.
It should write like this -
<Setter Target="Container.(Grid.HorizontalAlignment)" Value="Left" />
<Setter Target="Container.(Grid.VerticalAlignment)" Value="Top" />
I have some tips here for creating visual state setters without writing a single line of code.

windows 10 templated control and AdaptiveTrigger

How can I use AdaptiveTrigger in Templated Control in Windows 10 (I use Windows 10 Pro Insider Preview Build 10074). Window.Current.SizeChanged event do not fire up when window size change. What is proper way to make fluid control? Here is what I try to do, but nothing happens when change size of screen:
XAML template:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1">
<Style TargetType="local:CustomControl1" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CustomControl1">
<Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualSizeStates">
<VisualState x:Name="Small">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Rect.Fill" Value="Green"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Big">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="1000" MinWindowWidth="1000" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Rect.Fill" Value="Blue"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="Rect" Fill="Red" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
The trick is that you have to put VisualStateManager with AdaptiveTrigger-s into root control of ControlTemplate otherwise it will not work.
Here is example:
Generic.xaml -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AdaptiveLayoutExample">
<Style TargetType="local:CustomControl1" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CustomControl1">
<Grid x:Name="RootGrid">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="RootGrid.Background" Value="Yellow"/>
<Setter Target="MyGrid.Background" Value="White"/>
</VisualState.Setters>
</VisualState>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="600"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="RootGrid.Background" Value="Gray"></Setter>
<Setter Target="MyGrid.Background" Value="Red"></Setter>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="MyGrid" Width="50" Height="50" Background="Black"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MainPage.xaml -->
<Page
x:Class="AdaptiveLayoutExample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AdaptiveLayoutExample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<local:CustomControl1 Width="100" Height="100"/>
</Grid>
</Page>
I don't think AdaptiveTriggers works in a style like that. The only place I've got it to work is directly in a UserControl or a Grid inside a Page. I know for sure they don't work in a DataTemplate. The VisualStateManager must be before the controls content too I believe. Try a different approach like this:
<!--in app.xaml or something-->
<ControlTemplate x:Key="controlTemplate1" TargetType="MyControl">
<Border Background="Green"/>
</ControlTemplate>
<ControlTemplate x:Key="controlTemplate2" TargetType="MyControl">
<Border Background="Blue"/>
</ControlTemplate>
<!--in your page-->
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="visualStateGroup" >
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="control.Template" Value="{StaticResource controlTemplate1}"/>
</VisualState.Setters>
</VisualState>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="control.Template" Value="{StaticResource controlTemplate2}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<MyControl x:Name="control" Template="{StaticResource controlTemplate1}"/>
</Grid>
Not tested but let me know how that works out.
Please note that when you don't have a "Big" VisualState to trigger the default settings you will keep having the overwritten ones from the other VisualStates. Might be obvious, but it took some time for me to grasp it.