How to set page background in metro application - xaml

I have strange problem. I can't set background for my page in metro app.
Below is a simple view of my xaml structure
<Page Background="White">
<ListView Background="Red">
</ListView>
</Page>
The problem is that the background of the page is black. So I have red rectangle (ListView area) set on black background. I want my page to be white. I saw few examples and it seems that I did good. I've also tried with brushes but same result.

If you want your app to have a white background on all pages, then the easiest way to achieve this is to set the RequestedTheme on Light in the App.xaml file. This will not only give you a white background, but it will automatically change all other colors too, like the foreground color (for text etc.) will be black by default.
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...
RequestedTheme="Light">
For a single page I've always used a grid as rootcontainer in a page and that worked fine:
<common:LayoutAwarePage
x:Name="pageRoot"
...
>
<Grid Background="White">
Note that if you want to use an image as background instead of a color, you'll have to work with attached properties:
<Grid>
<Grid.Background>
<ImageBrush x:Name="backgroundGrid" ImageSource="/Assets/Paper.jpg" />
</Grid.Background>

I think the issue you're running into is that the default style for the page is overriding your attempt to set the background color.
If you look at the file StandardStyles.xaml, it includes a LayoutRootStyle (at the very end of the file). If you change the Value from the default to a hex color value (for example, #FFFF0000 would give you red), the background of the app will be changed correspondingly. This is a simple way to do what you want, but may not be a best practice.
<Style x:Key="LayoutRootStyle" TargetType="Panel">
<Setter Property="Background" Value="{StaticResource ApplicationPageBackgroundThemeBrush}"/>
<Setter Property="ChildrenTransitions">
<Setter.Value>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
Alternatively, you could set the background for the root Grid element, which would give you more granular control. Or you could create a custom style that overrides LayoutRootStyle in your page's Page.Resources section, by copying the rule into that section, and then modifying the Value of the Background setter.
Here's what it should look like:
<Page.Resources>
<Style x:Key="LayoutRootStyle" TargetType="Panel">
<Setter Property="Background" Value="#FFFF0000"/>
<Setter Property="ChildrenTransitions">
<Setter.Value>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
Hope that helps.

Related

AvaloniaUI Styles-pseudoclasses

I'm trying out styles in avalonia and most works, except for pseudoclasses, they just get ignored.
I have created a window and all styles are in there and I have created a user control (with a button on - the pseudoclasses are on the button), using the styles. I do not use code, only xaml to define the styles.
I have tried it out in the "Style Selector" for the button as "Button:pseudoclassname" and "Button.le:pseudoclassname". I have also tried "Button:pointerover" and "Button:hover" as the documentation mentions that that could be modified. No result. The styles for the pseudoclasses are all ignored, the others are all executed correct.
Is there something I'm doing wrong or is this a bug in avalonia ?
The xaml windows file:
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:Hub.Views"
xmlns:vm="using:Hub.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Hub.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Width="200" Height="300"
Title="Hub"
Classes="le">
<Window.Styles>
<Style Selector="Window.le">
<Setter Property="Background" Value="#191919"/>
</Style>
<Style Selector="Button.le">
<Setter Property="Background" Value="green"/>
<Setter Property="Foreground" Value="white"/>
</Style>
<Style Selector="Button.le:pointerover">
<Setter Property="Background" Value="red"/>
<Setter Property="Foreground" Value="white"/>
</Style>
<Style Selector="Button.le:pressed">
<Setter Property="Background" Value="blue"/>
<Setter Property="Foreground" Value="white"/>
</Style>
<Style Selector="TextBlock.le_update">
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="FontSize" Value="17"/>
<Setter Property="FontFamily" Value="Arial, Verdana"/>
<Setter Property="Foreground" Value="white"/>
<Setter Property="Background" Value="transparent"/>
</Style>
</Window.Styles>
<views:UpdateView/>
</Window>
The xaml user control file:
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Hub.Views.UpdateView">
<DockPanel>
<StackPanel DockPanel.Dock="Bottom">
<Button Classes="le" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Width="300">
Check for updates
</Button>
</StackPanel>
<StackPanel Spacing="5" Margin="5">
<TextBlock Classes="le_update" HorizontalAlignment="Center" Margin="4">
No updates for Hub.
</TextBlock>
<TextBlock Classes="le_update" HorizontalAlignment="Center" Margin="4">
No updates for Engine.
</TextBlock>
</StackPanel>
</DockPanel>
</UserControl>
Button's Background property does get affected by your style, but at that point it has no effect on the actual Button's background, because Background property controls only the normal state of the button.
If you take a look at the default Button style here you can see that it passes its background to ContentPresenter via TemplateBinding:
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter x:Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
but overrides ContentPresenter's background in a style like this:
<Style Selector="Button:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundPointerOver}" />
Since it's ContentPresenter that actually draws the background (Button is a lookless control), you'll see the button to have ButtonBackgroundPointerOver and not the Button's Background property value.
So, you need to write a style that changes the inner ContentPresenter like this:
<Style Selector="Button.le:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="green" />
</Style>
Unfortunately that makes your styles theme-dependent since control templates are different between default and fluent themes.
The answer Kekekeks gave is the correct one for the question I asked.
However, I use this space in the hope to help novice users of avalonia with no background in xaml at all, like I do. Most of us look at avalonia to give our apps an interface that works on Windows/Mac/Linux. To be honest, at the moment of writing, no real alternatives in c# exist.
At this moment Avalonia does have examples and some documentation that is good, but not so for people not really having a background in xaml.
Therefore, go to Udemy or LikedIn.Learning or Youtube or wherever you find a good course on WPF AND AFTER THAT go to the documentation of Avalonia and start playing around.
The similarities that both (Avalonia and WPF) share is enormous !!! And yes it is mentioned a few times in the docs, but a blunt "Do go and learn WPF first if you are new to xaml !" on the frontpage of the documentation would have saved me a fair share of time in trying to find it all out via the website.
Fair is fair, the project still is in beta and the website is already well documented for that stage, so no blame to the team !

ItemsControl with VirtualizingStackPanel disables horizontal animations in ScrollViewer

I'm building a custom XAML control for a UWP app that relies heavily on a ScrollViewer with snap points.
I would really like the content that is bound to the control to be virtualized, so I'm using an ItemsControl. However, when I use a VirtualizingStackPanel in the ItemsControl, and then call ChangeView() on the ScrollViewer to a specific HorizontalOffset, the animation effect when scrolling to the new offset is disabled (it just jumps directly to the offset). If I simply replace the VirtualizingStackPanel with a StackPanel (no virtualization), the horizontal animations work.
Question: Does anyone know how to use a VirtualizingStackPanel and enable horizontal animations when changing the offset?
Here is the C# adjusting the horizontal offset (the customScrollViewer is being accessed via tree-crawling, since it is part of the ControlTemplate style):
customScrollViewer.ChangeView(500, null, null, false);
And here is the XAML style for the ItemsControl:
<Style x:Key="ItemsControlSnapStyle" TargetType="ItemsControl">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer
x:Name="customScrollViewer"
VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="Auto"
HorizontalSnapPointsType="Mandatory">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Thanks!
Great question, I could reproduce this behavior, and it looks by-design. Derive from VirtualizingStackPanel document. It can only be used to display items in an ItemsControl. Generally. At the remarks part, Starting in Windows 8.1, ItemsStackPanel is used as the default ItemsPanel for ListView. If you modify the ItemsPanel, we recommend you use ItemsStackPanel or ItemsWrapGrid instead of VirtualizingStackPanel or WrapGrid.
If we replace VirtualizingStackPanel with ItemsStackPanel, and ChangeView method could work with animation. And ItemsStackPanel also support virtualizes. So we suggest you could use ItemsStackPanel as ItemsPanel for the ItemsControl.
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>

uwp adaptive gridview renders 1st element wrong

I am using AdaptiveGridView from UWP Community toolkit.
The Very first Item displays horribly wrong and all other Items are displayed just fine.
See in the picture below the 1st item has bigger Folder Image than others.
XAML
<Style TargetType="controls:AdaptiveGridView" x:Key="MainAdaptiveStyle">
<Setter Property="SelectionMode" Value="None"/>
<Setter Property="StretchContentForSingleRow" Value="False"/>
<Setter Property="DesiredWidth" Value="220"/>
<Setter Property="IsItemClickEnabled" Value="True"/>
<Setter Property="animations:ReorderGridAnimation.Duration" Value="400"/>
</Style>
<PivotItem Header="Folders">
<controls:AdaptiveGridView Name="FoldersLibraryGridView"
Style="{StaticResource MainAdaptiveStyle}"
ItemsSource="{x:Bind ViewModel.Folders}">
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate x:DataType="data:FolderItem">
<userTemplates:FolderTemplate />
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>
</PivotItem>
<....below is user control which is used the DataTemplate, known as FolderTemplate...>
<Grid >
<Grid.Resources>
<Style TargetType="Image" x:Key="ThumbImageStyle" >
<Setter Property="Stretch" Value="UniformToFill"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="8"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="8*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Border x:Name="ThumbImage" Grid.Row="0">
<Border.Background>
<SolidColorBrush Color="{ThemeResource SystemAccentColor}" Opacity="0.5"/>
</Border.Background>
<Image Source="ms-appx:///Assets/FolderIcon.png"
Style="{StaticResource ThumbImageStyle}"
/>
</Border>
<Border Background="{ThemeResource SystemAltHighColor}" Grid.Row="1" Padding="8,0,4,0">
<TextBlock Text="{x:Bind FolderItem.MyFolder.DisplayName}"
Style="{StaticResource GridViewVideoName}"/>
</Border>
</Grid>
UPDATE
as You can see in the picture below, market with red line, right side of each item is faded where the folder name textblock ends, and this occurs only when ItemHeight is Explicitly set on the ApativeGridView
I think the fix is simple. First have a look at the description of this control on GitHub -
/// <remarks>
/// The number and the width of items are calculated based on the
/// screen resolution in order to fully leverage the available screen space. The property ItemsHeight define
/// the items fixed height and the property DesiredWidth sets the minimum width for the elements to add a
/// new column.</remarks>
I believe ItemsHeight is a typo there. It really should be ItemHeight. You just need to specify it (e.g. <controls:AdaptiveGridView ItemHeight="280" ... /> and the problem should go away.
Update
Your second issue is related to the DropShadowPanel in the toolkit. If you resize the window a bit you will notice that the shadows then render properly.
I had a look at the default style of the control and the HorizontalContentAlignment property is set to Left initially. So it looks like the control doesn't properly resize its inner shadow component when the size is changed.
But since you have already got a local style, you can just set it to Stretch and the issue should go away.
<Style TargetType="controls:DropShadowPanel"
x:Key="MainDropShadow">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
Update 2
OK, so here is the reason why initially the shadow is not stretching -
The shadow size is calculated based on the Content of the DropShadowPanel control, but the shadow only monitors the SizeChanged event of the control to update its size.
What's happening in your case is that your Grid (direct child of the DropShadowPanel control) was initially arranged with a smaller size, then the shadow size was set, and then when the size of your Grid updates, because the size of DropShadowPanel is still with the same size, no SizeChanged will be invoked, hence the shadow size is not re-calculated. If you have the toolkit source code, you should be able to simply switch to monitor the SizeChanged of the Content instead and the problem should go away.
When you are setting HorizontalContentAlignment to Stretch, you are effectively saying "the child should have the same size of the parent". So when the shadow is initially sized, your Grid is already at the same size of its parent. But I feel like they must have been using Left for a reason and this should just be a temporary fix for your case.

UserControl style only visible in designer

I'd like to have page headers in my app with either an icon or text centered in a 50px high bar at the top of the page. Optionally with a back-button.
For this reason I use a UserControl on each page which gets either one of those styles applied: PageHeaderStyle or PageHeaderBackStyle.
My implementation of one of those is the following (style definition in my App.xaml):
<Style x:Key="PageHeaderBaseStyle" TargetType="UserControl">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Height" Value="50" />
<Setter Property="Width" Value="NaN" />
<Setter Property="Background" Value="{StaticResource CDColor}" />
</Style>
<Style x:Key="PageHeaderStyle" TargetType="UserControl" BasedOn="{StaticResource PageHeaderBaseStyle}">
<Setter Property="Content">
<Setter.Value>
<Grid Background="{StaticResource CDColor}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" DataContext="{StaticResource MainPageModel}">
<TextBlock Style="{StaticResource PageHeaderTextBlockStyle}" Text="{Binding Title}" Visibility="{Binding TitleVisibility}" />
<Image Style="{StaticResource PageHeaderIconStyle}" Source="{Binding Icon}" Visibility="{Binding IconVisibility}" />
</Grid>
</Setter.Value>
</Setter>
</Style>
Applied like it should be:
<UserControl Style="{StaticResource PageHeaderStyle}" />
Now first I had used "Template" and applied a DataTemplate with the grid component. But this didn't work. Then I changed it to directly set the Content of the UserControl. This does work: After building the designer shows the page header (before it showed only the blue selection border, but no content - it was transparent).
But as soon as I start debugging the app on the emulator it disappears and the running app only shows a blank spot where it should be.
Why is this so? I mean after all the designer already shows it, why does it disappear then, though?
FYI: I do not get any binding exceptions nor any other. It just doesn't show up.
PS: I tried setting the Background in the base style while setting the grid's background to transparent. This didn't work either - only a blank spot.
Solved the problem: Best approach is probably to use a ContentControl. Using the Content property did not work, though. You have to use the ContentTemplate property. Using that one does work just fine.

Applying different style to same control inside different containers

Is this possible using Xaml? For example, I have labels inside group boxes and toolbars. I have set labels' foreground color to white using Style in Xaml code.
Background color of the window is black so the group boxes have this background, as well. However, toolbar's background color is System.Media.Colors.Control (or whatever it is by default) and I'd like to keep it that way. The problem is that white isn't the best color on almost white (toolbar).
Is it possible to set Label's foreground color to be different depending on what its container is? And only in one place - in my case inside main window's Window.Resources tag.
Something like this:
<Style TargetType="Label">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="White"/>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ToolBar.Label">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Black"/>
</Setter.Value>
</Setter>
</Style>
Thanks,
J.
You can define the resources with the control e.g.
<ToolBar>
<ToolBar.Resources>
<Style TargetType="Label">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="White"/>
</Setter.Value>
</Setter>
</Style>
</ToolBar.Resources>
</ToolBar>
Then labels in your tool bar will pick the local resource.