I'm creating UWP Application where I need to show an array of results in a sliding menu. The sliding menu is scrollable and can be slide to change it's height like the search results in Maps Application in windows 10 mobile.
I can't find any tutorial to create such an experience.
Thanks in advance
You can use a UserControl
and UIElement.RenderTransform property to do this.
Here is a sample:
UserControl "SlidableControl" xaml:
<Grid x:Name="SlidRoot" ManipulationMode="All" HorizontalAlignment="Stretch" ManipulationStarted="SlidRoot_ManipulationStarted"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" ManipulationDelta="SlidRoot_ManipulationDelta"
ManipulationCompleted="SlidRoot_ManipulationCompleted">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Border x:Name="SlidArea" BorderBrush="Black" BorderThickness="1" Grid.Row="0" Height="{x:Bind maxheight}" Background="AliceBlue"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Child="{x:Bind SlidChild, Mode=OneWay}">
<Border.RenderTransform>
<CompositeTransform x:Name="SlidAreaTransform" TranslateY="{Binding ElementName=SlidTitle, Path=RenderTransform.TranslateY, Mode=TwoWay}" />
</Border.RenderTransform>
</Border>
<Grid x:Name="SlidTitle" Background="Gray" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1">
<Grid.RenderTransform>
<CompositeTransform x:Name="SlidTitleTransform" />
</Grid.RenderTransform>
<TextBlock Text="" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black" FontFamily="Segoe MDL2 Assets" FontSize="25" />
</Grid>
</Grid>
UserControl "SlidableControl" code behind:
private double maxheight;
private double Y;
private double finalY;
public SlidableControl()
{
this.InitializeComponent();
maxheight = Window.Current.Bounds.Height / 3;
SlidArea.Visibility = Visibility.Collapsed;
}
private void SlidRoot_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
SlidArea.Visibility = Visibility.Visible;
SlidTitleTransform.TranslateY = -maxheight;
}
private void SlidRoot_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
Y = e.Delta.Translation.Y;
finalY = SlidTitleTransform.TranslateY + Y;
if (Y >= 0 && finalY <= 0)
{
if (finalY < maxheight)
SlidTitleTransform.TranslateY = finalY;
else
SlidTitleTransform.TranslateY = 0;
}
else if (Y < 0 && finalY >= -maxheight)
{
if (finalY > -maxheight)
SlidTitleTransform.TranslateY = finalY;
else
{
SlidTitleTransform.TranslateY = -maxheight;
}
}
}
private void SlidRoot_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
if (finalY <= -maxheight)
{
SlidArea.Visibility = Visibility.Collapsed;
SlidTitleTransform.TranslateY = 0;
}
}
public static readonly DependencyProperty ChildProperty = DependencyProperty.Register("SlidChild", typeof(UIElement), typeof(SlidableControl), new PropertyMetadata(null));
public UIElement SlidChild
{
get { return (UIElement)GetValue(ChildProperty); }
set { SetValue(ChildProperty, value); }
}
You can see from my code, that I expose the SlidChild
property, so you can add any other control to this "SlidableControl" for example like this:
<local:SlidableControl VerticalAlignment="Top">
<local:SlidableControl.SlidChild>
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding txt}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</local:SlidableControl.SlidChild>
</local:SlidableControl>
This is a very early version of control, you can expose some other properties, like control's height.
Here is my demo, you can have a test.
This is the rendering image of my test:
Also you can use UserControl
to do this.
XAML:
<ScrollViewer x:Name="scrollViewer" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollMode="Disabled" VerticalScrollBarVisibility="Hidden">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border x:Name="Area1" Grid.Row="0" Height="{x:Bind childheight}" HorizontalAlignment="Stretch" Background="AliceBlue"></Border>
<Grid x:Name="SlidButton" Background="Gray" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1"
ManipulationStarted="SlidButton_ManipulationStarted" ManipulationCompleted="SlidButton_ManipulationCompleted"
ManipulationMode="All" ManipulationDelta="SlidButton_ManipulationDelta">
<TextBlock Text="" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black" FontFamily="Segoe MDL2 Assets" FontSize="15" />
</Grid>
<Border x:Name="Area2" Grid.Row="2" Height="{x:Bind childheight}" HorizontalAlignment="Stretch" Background="Transparent"></Border>
</Grid>
</ScrollViewer>
code behind:
private double height;
private double childheight;
public SlidableView()
{
this.InitializeComponent();
height = Window.Current.Bounds.Height * 2 - 40;
childheight = Window.Current.Bounds.Height - 40;
}
private void SlidButton_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
scrollViewer.VerticalScrollMode = ScrollMode.Enabled;
}
private void SlidButton_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
scrollViewer.VerticalScrollMode = ScrollMode.Disabled;
}
private static double Y;
private void SlidButton_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
Y = Y + e.Delta.Translation.Y;
scrollViewer.ChangeView(null, -Y, null);
}
This is a very simple version works on mobile, when it is applied on PC, please change the "height" and "childheight" like this:
height = Window.Current.Bounds.Height * 2 - 20;
childheight = Window.Current.Bounds.Height - 20;
And when I say this is a very simple version, because I didn't expose any property of this usercontrol, you can expose the both child property of two Border
controls as it in my last answer.
We Are looking to make modify on the behavior of your example in above, we want to change the behavior as the following image (the list should be on the map (blue Section) and the list motion from bottom to top as the image), what we should to change to do it?