How to add two tabs control in the same window WPF? - xaml

I have a page contains a tab Control and I'm trying to add another tab control in this page , I would like to know if I can do this with code?
<!--first tab Control-->
<TabControl VerticalAlignment="Bottom" Width="auto" x:Name="TabControl" Height="280" Grid.Row="2" FlowDirection="RightToLeft" BorderThickness="0">
</TabControl>
<!--second tab Control-->
<TabControl VerticalAlignment="Top" Width="auto" x:Name="TabControl" Height="280" Grid.Row="1" FlowDirection="RightToLeft" Grid.Column="0" Margin="-1,-5,10,15" BorderThickness="0" >
</TabControl>
I got this error when I've added the first tab Control :
Error The property "Content" can only be set once.

Well, i guess you removed the initial Grid container from your page.
Try to place your controls within a container
<StackPanel>
<TabControl />
<TabControl />
</StackPanel>

Related

uwp xbox app XYNavigation in Pivot Control

I am an experienced uwp developer but a beginner for uwp xbox platform. I am trying to set the XY Navigation for my app and trying to test it with keyboard (as I don't own a xbox myself).
I am using a Pivot view and I can easily navigate between the pivot items with right and left arrow keys, which makes sense. but when my settings page is selected with pivot option (settings pivot header is focused and settings pivot item is in view) then I try to shift my focus vertically downwards to the first control in the settings page (radio buttons) but I am not able to do it the focus remains on settings header and doesn't shift downward on the page.
So how can I shift the focus downwards from a pivot header to the 1st control within the page on pressing down, and vice versa i.e : when 1st control is focused I should move up to go back to the header of the pivot of that page, because I think that is the traditional navigation with pivot control on uwp xbox right?
Secondly the docs and the xbox app dev videos I watched recommended to set the focus on an element which makes sense, when the app loads, should that be done with this.Focus() method or is there a more efficient way to do it with xaml?
Code:
Pivot.xaml
<Grid x:Name="MainGrid">
<Pivot x:Uid="PivotPage" x:Name="MainPivot" >
<PivotItem x:Uid="PivotItem_OnNow">
<Frame>
<views:OnNowPage/>
</Frame>
</PivotItem>
<PivotItem x:Uid="PivotItem_Guide">
<Frame>
<views:GuidePage/>
</Frame>
</PivotItem>
<PivotItem x:Uid="PivotItem_Settings">
<Frame>
<views:SettingsPage/>
</Frame>
</PivotItem>
</Pivot>
</Grid>
Settings.xaml
<Grid>
<Grid Margin="{StaticResource MediumLeftRightMargin}">
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
x:Uid="Settings_Title"
x:Name="TitlePage"
Style="{StaticResource PageTitleStyle}" />
<StackPanel Grid.Row="1">
<TextBlock
x:Uid="Settings_Personalization"
Style="{StaticResource SubtitleTextBlockStyle}" />
<StackPanel Margin="{StaticResource SettingsSubheaderMargin}">
<TextBlock
x:Uid="Settings_Theme"
Style="{StaticResource BodyTextStyle}" />
<StackPanel Margin="{StaticResource EightTopMargin}">
<RadioButton
x:Uid="Settings_Theme_Light"
GroupName="AppTheme"
IsChecked="{x:Bind ViewModel.ElementTheme, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Light, Mode=OneWay}"
Command="{x:Bind ViewModel.SwitchThemeCommand}">
<RadioButton.CommandParameter>
<xaml:ElementTheme>Light</xaml:ElementTheme>
</RadioButton.CommandParameter>
</RadioButton>
<RadioButton
x:Uid="Settings_Theme_Dark"
GroupName="AppTheme"
IsChecked="{x:Bind ViewModel.ElementTheme, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Dark, Mode=OneWay}"
Command="{x:Bind ViewModel.SwitchThemeCommand}">
<RadioButton.CommandParameter>
<xaml:ElementTheme>Dark</xaml:ElementTheme>
</RadioButton.CommandParameter>
</RadioButton>
<RadioButton
x:Uid="Settings_Theme_Default"
GroupName="AppTheme"
IsChecked="{x:Bind ViewModel.ElementTheme, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Default, Mode=OneWay}"
Command="{x:Bind ViewModel.SwitchThemeCommand}">
<RadioButton.CommandParameter>
<xaml:ElementTheme>Default</xaml:ElementTheme>
</RadioButton.CommandParameter>
</RadioButton>
</StackPanel>
</StackPanel>
<TextBlock
x:Uid="Settings_About"
Style="{StaticResource SubtitleTextBlockStyle}"/>
<StackPanel Margin="{StaticResource EightTopMargin}">
<TextBlock
Text="{x:Bind ViewModel.VersionDescription, Mode=OneWay}" />
<TextBlock
x:Uid="Settings_AboutDescription"
Margin="{StaticResource EightTopMargin}" />
<HyperlinkButton
x:Uid="Settings_PrivacyTermsLink"
Margin="{StaticResource EightTopMargin}" />
</StackPanel>
</StackPanel>
</Grid>
</Grid>
The MSDN has listed several scenarios that XY navigation might not work the way you expect:
The IsTabStop or Visibility property is set wrong.
The control getting focus is actually bigger than you think—XY navigation looks at the total size of the control (ActualWidth and ActualHeight), not just the portion of the control that renders something interesting.
One focusable control is on top of another—XY navigation doesn't support controls that are overlapped.
If XY navigation is still not working the way you expect after fixing these issues, you can manually point to the element that you want to get focus using the method described in Overriding the default navigation.
Please first check these scenarios, after that, if you still could not solve this issue. Please provide a Minimal, Complete, and Verifiable example. I will help you diagnose it on my side.

UWP: how to hide a RelativePanel after 2 seconds

I have developed an UWP app allowing users to edit forms.
I would like to use a RelativePanel to show messages to the users on the Home page.
Theses message can concern forms management ("The form XXX has well been deleted", "The form XXX has well been saved"), or the synchronization ("Sync ended successfully", "Impossible to sync datas").
The Home page is based on a Grid that contains 3 rows:
a filter searchbox
the list of the forms
sync informations
Here is a screenshot of this page:
I would like to display the RelativePanel in the 3rd Row, above the sync informations, but only during 2 seconds. Then the RelativePanel will disappear, and the sync informations must be visible again.
I also encounter a problem with the width of the RelativePanel: I would like a left/right padding of 150, but it doesn't seem to work:
My XAML code looks like this:
<!-- User + Last sync-->
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding CurrentUser.username}" />
<StackPanel Grid.Column="1"
Orientation="Horizontal"
HorizontalAlignment="Right">
<TextBlock x:Uid="HomeTextBlockLastSync" Margin="0,0,8,0"/>
<TextBlock Text="{Binding LastSync, Mode=TwoWay}" />
</StackPanel>
</Grid>
<!-- Form Status message -->
<RelativePanel Grid.Row="2"
Background="Cyan"
Padding="150,0,150,0">
<StackPanel x:Name="FormStatusPanel" Orientation="Vertical"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.AlignVerticalCenterWithPanel="True">
<Border x:Name="FormStatusBorder" Margin="0">
<ScrollViewer VerticalScrollMode="Auto"
VerticalScrollBarVisibility="Auto"
MaxHeight="150">
<TextBlock Text="TestTestTest"
x:Name="FormStatusBlock" FontWeight="Bold"
TextWrapping="Wrap" />
</ScrollViewer>
</Border>
</StackPanel>
</RelativePanel>
=> Would you have an idea on why the Padding doesn't work? What is a better way to hide RelativePanel after 2 seconds? With the VisualStateManager or by the code?

UWP - GridView : how to add an "Add" button after the last item?

I use a GridView to display photos and I search an elegant way to allow user to add a new item to a form.
The form contains a lot of fields: it is displayed in a Pivot, where each PivotItem represents a category of the form.
Some categories contain one or more child items: they are displayed through a Master-Detail page.
It's in this page that I need to display a list of photos: as a photo represents a "sub sub item" of the form, I wouldn't manage the add of a new photo through the CommandBar. But I would like to use an "Add" button after the last item of the GridView containing the photos.
At this time I only found a solution that partially work:
Here is the XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Photos" Grid.Row="0"/>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<GridView ItemsSource="{Binding images}">
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Image Stretch="UniformToFill"
Source="{Binding bitmap_image}" />
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Button Command="{Binding Path=DataContext.AddPhotoCommand, ElementName=DetailsPage}"
Height="100" Width="100">
<Viewbox>
<SymbolIcon Symbol="Add"/>
</Viewbox>
</Button>
</Border>
</StackPanel>
</Grid>
As I use a StackPanel, the Add button is no longer visible if I display 3 photos...
=> Is there a better way to do this? Or do you see a an alternative? I'm looking for doing this through a DataTemplateSelector, but that would require me to create a "false" object for displaying the add button...
As I use a StackPanel, the Add button is no longer visible if I display 3 photos...
If you don't mind the button is in the next line of your last photo, you can use WinRTXamlToolkit's WrapPanel instead of StackPanel to avoid the pictures goes out of the window and put the button inside the GridView's FooterTemplate:
Xaml:
<Page
x:Class="AddButtonSample.MainPage"
xmlns:controls="using:WinRTXamlToolkit.Controls"
...
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Photos" Grid.Row="0"/>
<controls:WrapPanel Orientation="Horizontal" Grid.Row="1">
<GridView ItemsSource="{Binding images}">
<GridView.FooterTemplate>
<DataTemplate>
<Button Command="{Binding Path=AddPhotoCommand}" Height="100" Width="100">
<Viewbox>
<SymbolIcon Symbol="Add"/>
</Viewbox>
</Button>
</DataTemplate>
</GridView.FooterTemplate>
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Image Stretch="UniformToFill"
Source="{Binding bitmap_image}" />
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</controls:WrapPanel>
</Grid>
Result:
If you really want to put the Button side by side after the last item of GridView. The only Option is DataTemplateSelector.
The best solution might be to use a CommandBar and put the "Add" button in the very bottom of the panel, as that would be most consistent with UWP design guidelines. GridView also has a FooterTemplate, which allows you to add some XAML in the footer of the whole GridView (but not directly after the items).
If you still want to have the add item as part of the GridView contents, you will really need to use the fake item and a DataTemplateSelector. This solution is not very clean, but probably is the only simple way.
I tried to do something similar for my own app too, but there really isn't an obvious way to achieve it. A little background on what my app does: it's a flashcard app that displays decks of card in a gridview on the homepage, with an add button being at the front of the gridview. This is what I did:
for my deck class, I gave it a bool attribute isButton
in the observablecollection of decks, set the first item's isButton to true
make two datatemplates for the gridview (deck and button) and make a data template picker for the gridview, and check the isButton attribute
if isButton is true, the template picker will use the button template
otherwise use deck template

Show Button if GridViewItem is selected

I have WinRT application with following GridView:
<GridView x:Name="RouteGrid"
ItemsSource="{Binding Routes}"
SelectedItem="{Binding SelectedRoute,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}"
SelectionMode="Single">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Width="300" Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock FontWeight="Bold" Text="{Binding TermText}" />
<TextBlock Grid.Column="1" Text="{Binding ConnectionObjects.Count}" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
I want to show a button instead of the second textblock when ever the item is selected because I want to allow my users to navigate to another view when they've selected.
I would like to do it in pure XAML because that is for me the cleanest way but I have no idea how to bind to the IsSelected property of the GridViewItem.
In WPF I would bind the Visibility property of the TextBlock and the button with a BooleanToVisibilityConverter and RelativeSource to the AncestorType GridViewItem and its property but that's not working because WinRT does not know AncestorType :(
Thanks for help.

Highlighting around GridView items

I started off with a Grouped Items Page template and have my data displaying in groups. I added some margins around these items to improve spacing, but now when I hover over these items, the margin area shows as highlighted. I'm sure this is an easy one for xaml gurus. Please assist!!
Here's my markup:
<GridView.ItemTemplate>
<DataTemplate>
<!-- ******************* here is my margins ******************* -->
<Border BorderBrush="LightGray" BorderThickness="2" Margin="0,0,20,20">
<Grid HorizontalAlignment="Left" Width="390" Height="190">
<Grid.Background>
<ImageBrush ImageSource="/Assets/default.png" Stretch="None"/>
</Grid.Background>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<Image VerticalAlignment="Top" Stretch="None" Source="{Binding ImageUrl}" Margin="10,10,0,0"/>
<StackPanel MaxWidth="270">
<TextBlock Text="{Binding Summary}"/>
<TextBlock Text="{Binding Brand}" />
<TextBlock Text="{Binding Detail}" TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
Your ItemTemplate just populates over the existing style template for the GridViewItem Style which if you look in the default template shown in that link you'll see a Rectangle named "PointerOverBorder" which is shown (via the VisualStateManager) in the PointerOver state with its Fill set to ListViewItemPointerOverBackgroundThemeBrush.
You could go into the template (right-click, edit template) and remove it, or add your margins, or make it transparent or a number of options. Or could just overwrite the brush resource on the instance to be transparent or something kind of like;
<blah.Resources>
<SolidColorBrush x:Key="ListViewItemPointerOverBackgroundThemeBrush" Color="Transparent" />
</blah.Resources>
Hope this helps.