ItemControl background color - xaml

In a fresh Universal Windows Platform app, I am trying to set the Background of an ItemsControl. But it doesn't seem to do anything. The only changes I've made to the VS template are in MainPage.xaml, which now looks like this:
<Page
x:Class="UWPPlayground.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPPlayground"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Name="Hello">
<Grid Background="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*">
</ColumnDefinition>
<ColumnDefinition Width="*">
</ColumnDefinition>
</Grid.ColumnDefinitions>
<ItemsControl Grid.Row="0" Grid.Column="0" Width="60" Height="30" Foreground="Wheat" Background="White">
<TextBlock Text="Hello World!"></TextBlock>
<TextBlock Text="Can you see this?"></TextBlock>
</ItemsControl>
<Grid Grid.Row="0" Grid.Column="1" Background="Purple"></Grid>
</Grid>
</Page>
The result is shown below. The Foreground property of the ItemsControl seems to be working just fine, as the TextBlocks have wheat-colored text. Due to the small size of the control, the text is cut-off, as expected. The Background, however, is not visible. What am I missing?

ItemsControl inherits from Control, which defines lots of visual properties at the base class level which do not necessarily influence the appearance of the control directly. These properties are usually referenced via TemplateBindings in the ControlTemplate, which then gives rise to the desired appearance. Whether or not the template uses these properties determines whether or not they have any use at all.
You'll notice that changing a UserControl's background also does nothing (for the same reason mentioned above).
Non-control classes like Grid, Rectangle, Border (etc) do honor such properties out of the box, since these are the elements typically used in the templates of controls to produce a certain appearance.
The reason why ItemsControl-derived classes (like ListView) do honor the background property is because some root-level element in its template references the Background property (via TemplateBinding). ItemsControl on its own has no template.
I think the reason why the Foreground property works is because it will inherit its value from the parent. (Some dependency properties can inherit their values like this).
The easiest way to set a background for your ItemsControl would be to wrap it in a Border (or Grid, they're essentially the same now) and set a background brush on that instead.
I don't recommend you do what follows for your example, but this is what you would need to do if you wanted the Background property to work:
<ItemsControl Background="Red">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Grid Background="{TemplateBinding Background}">
<ItemsPresenter/>
</Grid>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>

Related

UWP PersonPicture control background not being set

PersonPicture is a control offered in Microsoft's Universal Windows Platform.
It looks great, which is why I'm trying to use it to display a user's initials with a background color.
The problem is that when I set the control's background to a color, the background is not changed on the display.
<PersonPicture Initials="JF"
Background="Red"/>
In the above code, the Background still remains the default, while everything else is updated.
Please if you have been able to set the background color, share how you've done it!
I found the template for the PersonPicture through this question: How to get all Controls' ControlTemplates Programmatically?(UWP)
The PersonPicture ignores its Background property and uses a couple of brushes that make up the colors of the control depending on Dark/Light theme and some hard coded values.
It draws an ellipse/circle and thus shows its container's color in the four corners.
Assuming you want to set the color in the square that contains the picture you could do this:
<Grid Background="Green">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Red">
<PersonPicture />
</Grid>
</Grid>
The first grid represents a page. The second grid tightly wraps around the PersonPicture:
Note how the personpicture is somewhat transparent and shows the color of the grid. The color that the template uses for the ellipse is #77FFFFFF
So you could take it a step further by adding an ellipse:
<Grid Background="Green">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Red">
<Ellipse Fill="White"/>
<PersonPicture />
</Grid>
</Grid>
This allows you to control the color of the picture somewhat by setting the color of the ellipse:
Do note that it still mixes the PersonPicture with the background so you cannot set it to black:
<Grid Background="Green">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Red">
<Ellipse Fill="Black" />
<PersonPicture />
</Grid>
</Grid>
Shows:
And finally, you could copy the template (see: How to get all Controls' ControlTemplates Programmatically?(UWP))
and adjust it to use the Background property.

ContentDialog's buttons are not shown in a Windows Phone 8.1 app if the BottomAppBar is defined

I would like to show a ContentDialog on first launch of my app, to show the EULA to the end user.
It seems that if an AppBar is defined in the calling page the two buttons in the dialog are not visible, an empty area with the same size of the command bar area defined in the calling page, is shown instead.
This is the markup on the ContentDialog:
<ContentDialog
x:Class="MyApp.EulaPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="TERMS OF USE"
PrimaryButtonText="i agree"
SecondaryButtonText="cancel"
PrimaryButtonClick="OnAgreeButtonClick"
SecondaryButtonClick="OnCancelButtonClick">
<Grid x:Name="ContentPanel" Margin="0,0,0,0" >
<Grid.RowDefinitions>
<RowDefinition Height="524" />
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="0" Margin="0,0,0,2" >
<RichTextBlock IsTextSelectionEnabled="False" TextAlignment="Left" TextIndent="0" FontSize="14" FontFamily="Segoe WP" >
</RichTextBlock>
</ScrollViewer>
</Grid>
The GridRowDefinition has a fixed hight, because the text in the RichTextBlock needs to be scrolled.
I have prepared a sample project that can be found here. The zip file contains also a screenshot showing how I see the dialog.
I had the same problem and I have solved it by modifying/removing Height/Width and Margins of the Contentdialog

GridView vs Buttons

I have a grid of 12 non clickable buttons(they are just indicators) in the center of my page in the following manner.
There is going to be more stuff around this grid and I need the items to be at their exact place and of the same width and height. I am confused whether to use a grid with (star sized) rows and columns with buttons in them or a gridview with a wrap panel with MaxRowsAndColumns set to 3 and Orientation set to Horizontal. Here are my arguments for and against each of the approaches:-
Buttons:-
Pros:-
Fixed position and height and width guaranteed.
Adaptable to all screen sizes
Easy to code
Cons:-
Will have to write a very large XAML and C# code because I will not be able to use Data Template here and will have to define lots of variables and grids and set values of each textblock separately.
GridView
Pros:-
DataTemplate available so easy to set values via ObservableCollection
Smaller code than the one created using buttons
Cons:-
No guarantees of item size. Will have to hard code it in XAML or Bind it to properties in Model and then calculate the value inside XAML.
Please let me know which one is the better alternative.
Is there any other easier way to do it apart from the methods mentioned above?
Thanks,
Rajeev
Use ItemsControl, it offers DataTemplate as well as item size.
Out of the two above I would say GridView. Since you need to support so many different screen sizes and ratios you shouldn't have fixed sizes.
As the guidelines states: Guidelines for window sizes and scaling to screens(Windows Store apps)
Design apps that look good at any width, and you automatically get
support for different screen sizes and orientations. Plan your app for
resizing from full screen down to the minimum width so that the UI
reflows gracefully for various screen sizes, window sizes, and
orientations.
Since you also need to cater for the snapped mode (which you can't choose not to have in you application) having buttons will add even more manual work which means a lot of hard to maintain UI code. If you use a gridview you can pair it up with a listview for the snapped mode (gridview for full mode, listview for snapped) as in the templates.
You can certainly restrict the sizes in a GridView without it require even a fifth of the work needed for buttons, so I'm not quite sure what you mean by "No guarantees of item size".
Anyway, as the guidelines says, buttons should NOT be used for navigation to a page. These are just guidelines, but I reckon they make sense.
Here are: Guidelines and checklist for buttons (Windows Store apps)
Don't use a button when the action is to navigate to another page; use
a link instead. Exception: For wizard navigation, use buttons labeled
"Back" and "Next".
I would use GriView and combine it with a semantic zoom if appropriate.
Example with GridView and ItemsControl, here is the result:
Code for the UI (View):
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<GridView x:Name="gridView">
<GridView.ItemTemplate>
<DataTemplate>
<Border Width="150" Height="150" BorderBrush="Pink" BorderThickness="10" Background="Aqua">
<TextBlock Foreground="Black" FontSize="20" Text="{Binding}"/>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<ItemsControl Grid.Row="1" x:Name="itemscontrol">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="150" Height="150" BorderBrush="Yellow" BorderThickness="10" Background="LightGreen">
<TextBlock Foreground="Black" FontSize="20" Text="{Binding}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</Page>
Code for the codebehind (the .cs file that belongs to the XAML):
using System.Collections.Generic;
namespace App1
{
public sealed partial class MainPage
{
public MainPage()
{
InitializeComponent();
DataContext = this;
var items = new List<string> { "Iris", "Paul", "Ben", "Cate", "Daniel", "Ryan", "Iris 2", "Paul 2", "Ben 2", "Cate 2", "Daniel 2", "Ryan 2" };
gridView.ItemsSource = items;
itemscontrol.ItemsSource = items;
}
}
}
The result at a higher resolution, notice that the items keep their fixed size and don't scale to fit the screen.
Stretching the items height over one row with the GridView:
<GridView x:Name="gridView">
<GridView.ItemTemplate>
<DataTemplate>
<Border Width="150" BorderBrush="Pink" BorderThickness="10" Background="Aqua">
<TextBlock Foreground="Black" FontSize="20" Text="{Binding}"/>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
By the way, GridView inherits from the ItemsControl if you didn't know.

I cant place or set background or border of my user control

I've created a simple user control for my xaml project, but as you can see from my image i cant seem to be able to do certain things.
Ignore the red line, its the size of the control for illustrate its size.
It's placement should be middle of the screen:
<Client:TileMenu HorizontalAlignment="Center" VerticalAlignment="Center" Name="TileOverlayMenu" Background="Azure" BorderBrush="Aquamarine" BorderThickness="3" />
And as you see its background color should be "Azure" with a blueish border of 3.
Why is this?
In the background I have a Canvas:
<Grid x:Name="ContentPanel" Grid.Row="0" Margin="12,0,12,0">
<Canvas Name="GameCanvas">
<Canvas.RenderTransform>
<CompositeTransform x:Name="CanvasRenderTransform" />
</Canvas.RenderTransform>
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener DragStarted="GestureListener_DragStarted" DragDelta="GestureListener_DragDelta" Tap="GestureListener_Tap" PinchStarted="GestureListener_PinchStarted" PinchDelta="GestureListener_PinchDelta"/>
</toolkit:GestureService.GestureListener>
</Canvas>
<Client:TileMenu HorizontalAlignment="Center" VerticalAlignment="Center" Name="TileOverlayMenu" Background="Azure" BorderBrush="Aquamarine" BorderThickness="3" />
</Grid>
As for my third problem, having the events in the canvas causes the Move slider to be interrupted, making me only able to push it a little each time :-/
In case TileMenu is a UserControl you would have to set these properties on the top level container in the UserControl's XAML as this defines the entire visual structure of the control.
You could bind to the appropriate values in the UserControl, however:
<UserControl x:Class="YourNamespace.TileMenu" ...
x:Name="tileMenu">
<Border BorderBrush="{Binding BorderBrush, ElementName=tileMenu}"
BorderThickness="{Binding BorderThickness, ElementName=tileMenu}">
<Grid>
...
</Grid>
</Border>
</UserControl>

How to set a RichTextBox in Silverlight 4 to fit it's parent height and maintain it on resize?

I am having hard times figuring this out. Here is what I need:
<StackPanel x:Name="container" VerticalAlignment="Stretch">
<RichTextBox Height="???" />
</StackPanel>
Basically what I know I can do is to bind RichTextBox Height to it's parent's height ( Height="{Binding ElementName=container, Path=ActualHeight}". Unfortunately this only works on load, because as it seems ActualHeight and ActualWidth don't notify for changes.
So what is the best way in Silverlight 4 to tell RichTextBox or TextBlock, it doesn't matter, to fill it's parent height, and maintain scrollbar if it's content height is bigger. Is the only way to bind some Resize events and maintain the height explicitly? That seems really ugly to me? Have anybody had this problem as well?
Any resources or information is highly appreciated! Thanks.
Ivan,
The best way to solve this is to use a Grid as the parent for the RickTextBox, instead of a StackPanel. By default, a Grid will "Strectch" its content to take up all of the available space. A StackPanel will only Stretch its content in one diminsion.
As an example, paste the following XAML into my XamlViewer to see the difference:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<RichTextBox
Foreground="Blue" FontSize="24" Background="Yellow">
<Paragraph>RichTextBox inside a StackPanel</Paragraph>
</RichTextBox>
</StackPanel>
<Grid Grid.Row="1">
<RichTextBox
Foreground="Blue" FontSize="24" Background="Tan">
<Paragraph>RichTextBox inside a Grid</Paragraph>
</RichTextBox>
</Grid>
</Grid>
</UserControl>
Good luck,
Jim McCurdy, Face to Face Software and YinYangMoney