I included MasterDetail control (2. approach) from Template10 Samples project into a simple Template10 Hamburger menu application. It is working fine, but in VisualStateNarrow MasterCommandBarContent will be displayed behind Hamburger menu button. Also the back button in detailed view will not be "visible" because button is behind Hamburger menu button, too. Exactly in this time, detailed page will shown beside master page, header content will be displayed the right way. Of course this behavior will not happen at another page with a "normal" PageHeader control. I cannot find this piece of xaml code to fix this issue.
Thanks for some hints
Solution is so simple, just add a Padding to
DetailsCommandBar
and
MasterCommandBar
Here a part of my custom.xaml file:
<Style TargetType="localControls:MasterDetailsView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="localControls:MasterDetailsView">
<Border
x:Name="ControlRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="CommandBarRow" Height="Auto" />
<RowDefinition x:Name="ContentRow" Height="*" />
<RowDefinition x:Name="MobileCommandBarRow" Height="0" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="MasterPane" Width="{Binding MasterPaneWidth, RelativeSource={RelativeSource TemplatedParent}}" />
<ColumnDefinition x:Name="DetailsPane" Width="*" />
</Grid.ColumnDefinitions>
<CommandBar
x:Name="DetailsCommandBar"
Grid.Row="0"
Grid.Column="1"
Padding="48,0,0,0">
<CommandBar.Content>
</CommandBar.Content>
</CommandBar>
<CommandBar
x:Name="MasterCommandBar"
Grid.Row="0"
Grid.Column="0"
Padding="48,0,0,0">
<CommandBar.Content>
</CommandBar.Content>
</CommandBar>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Related
ListView is placed inside UserControl which is set in parent XAML to asterix "*" height.
I want to use ListView with possibility to scroll items, when there are items that exceed ListView. It should work for different size of window.
It works fine when I set Grid's RowDefinitions with fixed integer, but when I try to use asterix "*" ScrollViewer disables.
I also tried to bind and update RowDefinition's height via some code behind in overriden MeasureOverride method, but it didn't work as expected.
Here is code inside my UserControl:
<Grid x:Name="ContentArea"
Background="{StaticResource MixerBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="{x:Bind ListViewHeight}" />
</Grid.RowDefinitions>
<ListView
ItemsSource="{x:Bind ViewModel.Source,Mode=TwoWay}"
CanDragItems="True"
CanReorderItems="True"
AllowDrop="True"
SelectionMode="Single"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:Track">
<Grid
Background="LightGray"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
BorderBrush="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<TextBlock
Text="{x:Bind Id}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="24"
Margin="20,5,20,5"/>
<Grid
Background="Black"
Width="500"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Column="1">
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I expect to get the ScrollViewer working correctly, but ListView stay at the old size or scroll bar is disabled - depending on Height value.
Is there any way to achieve dynamically resizing ListView with scroll?
Edit
Here is parent Page XAML code which is loaded into Frame via Light MVVM framework:
<Grid
x:Name="ContentArea">
<Grid
Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
<RowDefinition Height="300" />
</Grid.RowDefinitions>
<maineditor:MainEditorMenuControl x:Name="ProjectMenu" />
<maineditor:MainEditorWorkspaceControl x:Name="Workspace" Grid.Row="1"/>
<maineditor:MainEditorMixerControl x:Name="Mixer" Grid.Row="2" />
</Grid>
</Grid>
Edit 2
I think the problem may be connected with MVVM template I've created with Windows Template Studio plugin for Visual Studio. If I try to recreate minimal solution from scratch with all properties 1:1 as in my app it works in fresh project, but not in mine.
How to dynamically update ListView height while keeping the ScrollViewer enabled?
If you want make RowDefinition height same as the ListView, you could give the ListView a name and use {Binding ElementName=MyListView,Path=ActualHeight}syntax to bind both height property.
<Grid x:Name="ContentArea">
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=MyListView,Path=ActualHeight}" />
</Grid.RowDefinitions>
<ListView
Name="MyListView"
CanDragItems="True"
CanReorderItems="True"
AllowDrop="True"
Loaded="MyListView_Loaded"
SelectionMode="Single"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.ItemTemplate>
<DataTemplate >
<Grid
Background="LightGray"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
BorderBrush="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<TextBlock
Text="{Binding}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="24"
Margin="20,5,20,5"/>
<Grid
Background="Black"
Width="500"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Column="1">
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
I have a proble which seems pretty common and has been asked alot, but I can't find a fixing solution for my problem.
So I try to use 3 listviews in in one page all shall have a title and an explaining image, but instead of designing all 3 ListViews in one page I outsourced one listview with image and title into a control, which I use in my page.
The 3 Controls are placed in a grid. When the listview items get filled thy scrollbar should become visible if the remaining space is no longer enough but it won't show.
I provided a sandbox project where I placed the control and etc. like in the application I'm working on. SampleProject
Their you just need to press start and the listviews get filled. But they don't show the scrollbar.
Thanks in advance!
Edit 1:
As requested I share my code below. If you open up the sample project then you do not need to read further until a second edit is done.
Control containing listview:
<Grid>
<Grid x:Name="Section"
HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="grdTitleArea"
HorizontalAlignment="Stretch"
Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<BitmapIcon
VerticalAlignment="Center"
HorizontalAlignment="Center"
Tapped="grdTitleArea_Tapped"
UriSource="ms-appx:///Assets/area.png"
Height="40" />
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Tapped="grdTitleArea_Tapped"
Text="Area"
Grid.Column="1" />
</Grid>
<!--<ScrollViewer
VerticalAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
VerticalScrollMode="Enabled"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
HorizontalScrollBarVisibility="Hidden"
HorizontalScrollMode="Disabled"
>-->
<ListView x:Name="ListView"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Auto"
Grid.Row="1">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="1"
Margin="1"
Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding ActionDescription}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--</ScrollViewer>-->
</Grid>
</Grid>
Control which contains the control above 3 times:
<Grid x:Name="ProgressControl">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:SynchronizeSettingsControl
Visibility="Visible"
x:Name="Settings" />
<local:SynchronizeSectionControl
x:Name="ActualAction"
Visibility="Visible"
Grid.Row="1" />
<local:SynchronizeSectionControl
x:Name="Error"
Visibility="Visible"
Grid.Row="2" />
<local:SynchronizeSectionControl
x:Name="Log"
Visibility="Visible"
Grid.Row="3" />
</Grid>
Page which contains the control which contains the listview:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1"
Text="Demo"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Width="70"
VerticalAlignment="Stretch"
Content="Useless Button" />
</Grid>
<Controls:SynchronizeControl
x:Name="ctlSync"
Grid.Row="2"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
<Button VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
x:Name="btnStart"
Content="Start"
Tapped="btnStart_Tapped"
Grid.Row="3" />
</Grid>
The problem is you used Auto height in the page. This means basically that the page tells the local:SynchronizeSectionControl control: "You can use whichever height you want".
The control then has * as the height of the second row which means "use the rest space available". But because the page offered essentially "infinite height", the ListView height will stretch as much as possible to accommodate for all its items and hence it doesn't scroll, as its height is big enough to display everything, although it is cut off and not visible, because the window height is of course limited.
The thing is you used the Auto property for the height of your rows in your control.
This works fine is the control you use uses a definite space. Like a button or similar stuff. But when the control can extend indefinitely the allocation for the space gets screwed up.
Basically the control displays at its maximum size but extends way over its boundaries.
You can prevent that when you use the * as a Height value.
This will lead to the control taking up all the space available. You can further limit this with using the MaxHeight property.
If you do it that way it will display a scrollviewer when necessary and it will even resize when you change the window size.
I have a GridView that uses a DataTemplate to provide a UI so users can manage subscriptions to a dataservice. The DataTemplate contains text and an image and also a Button and a ToggleButton. Using this on Mobile and Desktop the user can tap or click the buttons within the control. On Desktop you can even Tab inside the control and select the buttons. However on Xbox I am only able to focus on each DataTemplate item, I cannot get it to focus on the buttons inside, is there a way around this without enabling Mouse Mode on the Xbox?
<DataTemplate x:Key="DataTemplate1">
<Grid Background="#33FFFFFF">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="80" Source="{Binding TEAMID, Converter={StaticResource uriConverter}}" Grid.RowSpan="3"/>
<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="{Binding TEAMNAME}" VerticalAlignment="Top" Grid.Column="1"/>
<Button Content="Unsubscribe" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" Tag="{Binding TEAMID}" Tapped="Button_Tapped"/>
<ToggleButton x:Name="subscribe_tb" Content="" HorizontalAlignment="Center" FontFamily="Segoe MDL2 Assets" Tag="{Binding TEAMID}" IsChecked="{Binding isPinned}" Grid.Row="3" Grid.Column="1" Unchecked="subscribe_tb_Unchecked" Checked="subscribe_tb_Checked"/>
</Grid>
</DataTemplate>
Solved by changing the Style of the GridView.ItemContainerStyle:
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="IsFocusEngagementEnabled" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>
I'm writing a UWP app and have several areas where searches are performed and results are rendered in a ListView where the ItemTemplate is defined inside a DataTemplate. Nothing fancy is going on here - just returns a list of items in a single "column", if you will.
There are three supported screen states (or widths), 320, 640, and 1024. I'd like to render these search results in two "columns" when the screen state is 640 or 1024 (wide states).
I'd like to use adaptive triggers for this task, but I'm at a loss of how to do this intelligently. There are examples of creating different views for each device family, but they seem too dependent on checking the device family. Best practices dictate using screen width thresholds instead. Either way, it seems this could easily be accomplished using adaptive triggers.
Any insight or examples of where this is done would be appreciated. The code is included to provide more context and to act as my starting point.
<Page.Resources>
<ResourceDictionary>
<Style x:Key="TextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource LargeTextBlockStyle}">
<Setter Property="Foreground" Value="{StaticResource TitleBrush}" />
</Style>
<DataTemplate x:Key="SearchResult">
<StackPanel Width="{Binding ActualWidth, ElementName=Parent}">
<Border Background="Gray" MinWidth="235">
<Grid Height="155">
<Image Source="{Binding SearchResultImage}"
Style="{StaticResource ImageStyle}" />
<Rectangle Fill="{StaticResource BackgroundBrush}" />
<StackPanel Margin="10,10,15,10" VerticalAlignment="Center">
<TextBlock Text="{Binding SearchResultName}"
Style="{StaticResource TextBlockStyle}"
VerticalAlignment="Center" />
</StackPanel>
</Grid>
</Border>
<Button Style="{StaticResource ButtonStyle}"
Command="{Binding ViewRecipeCommand, Source={StaticResource Locator}}"
CommandParameter="{Binding}">
<StackPanel Margin="0" Orientation="Horizontal" HorizontalAlignment="Center">
<SymbolIcon Symbol="Calendar" Margin="0,0,10,0" />
<TextBlock x:Uid="ViewRecipeCommandTextBlock"
Text="View Recipe"
Style="{StaticResource TextBlockStyle}" />
</StackPanel>
</Button>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</Page.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderStackPanel" Grid.Row="0" Margin="10">
<TextBlock x:Uid="RecipesTitle" Text="All Recipes"
Style="{StaticResource TextBlockStyle}"
Margin="0,0,0,10" />
</StackPanel>
<ListView x:Name="ResultsListView" Grid.Row="2"
ItemsSource="{Binding AllRecipes}"
ItemTemplate="{StaticResource SearchResult}" />
</Grid>
What I'd do to use a GridView instead a ListView, and change the GridView's ItemsPanel based on the width changes.
By using a GridView with an item width as wide as the screen size (320) you can get it to behave like a ListView, and if the GridView get's wider the content will automatically produce two columns for you. The only thing not to forget is to change the default scrolling direction of the ItemsPanel from horizontal to vertical.
I have a ListBox with images as items, I need each image to take the full width of the screen, and to be center-locked (like ViewPager in android)
this is what I have so far:
<Grid x:Name="ContentPanel" Grid.Row="1" VerticalAlignment="Bottom">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Grid.Row="1" ItemsSource="{Binding Zones[0].listBannieres}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding banniere}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
thank you.
SOLVED
<phone:PivotItem Header="Zone 1" Margin="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" VerticalAlignment="Bottom" >
<phone:Pivot ItemsSource="{Binding Zones[0].listBannieres}">
<phone:Pivot.HeaderTemplate>
<DataTemplate />
</phone:Pivot.HeaderTemplate>
<phone:Pivot.ItemContainerStyle>
<Style TargetType="phone:PivotItem">
<Setter Property="Margin" Value="0"/>
</Style>
</phone:Pivot.ItemContainerStyle>
<phone:Pivot.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding banniere}"/>
</StackPanel>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
</StackPanel>
</Grid>
</phone:PivotItem>
I would recommend using Pivot as suggested in the comments or a Panorama control, if you place those inside another control, you can have them visible at the bottom only. Here is an example with pivot:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="200" />
</Grid.RowDefinitions>
<phone:Pivot Grid.Row="1" ItemsSource="{Binding Images}" Margin="0">
<phone:Pivot.HeaderTemplate>
<DataTemplate></DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:Pivot.ItemContainerStyle>
<Style TargetType="phone:PivotItem">
<Setter Property="Margin" Value="0" />
</Style>
</phone:Pivot.ItemContainerStyle>
<phone:Pivot.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImagePath}" Stretch="Fill" />
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
</Grid>
Here only the bottom part is scrolled to as you wanted. It will also "snap" to the images when scrolling, which I also think the Android viewpager does. :)
If you instead change Pivot to Panorama and PivotItem to PanoramaItem you can get another nice result, where you see a small part of the next image. Here is an image of the result:
Edit: To remove the margin and headers, make sure you set the HeaderTemplate to an empty one and the Margin on PivotItem to 0. See the updated code above.