Create slidable ListView in Windows 10 UWP apps like in Maps app

你。 提交于 2019-12-20 06:32:01

问题


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


回答1:


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="&#xE76F;" 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:




回答2:


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="&#xE76F;" 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.




回答3:


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?



来源:https://stackoverflow.com/questions/36202429/create-slidable-listview-in-windows-10-uwp-apps-like-in-maps-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!