How to set vertical offset for popup having variab

2019-06-26 06:32发布

I am developing Windows 8 (I know Windows 8.1 has Flyout control) app using C#/XAML. I want to show a flyout menu like given below. Now originally it has total 10 options but based on context I am showing certain amount of options, so the usercontrols doesn't have fixed height, it's Auto.

I followed this article to correctly appear flyout on appbar button click. But it's not useful for me because it's using usercontrol's height and for my case it's NaN.

So any one has any better solution to show flyout with variable height.

PS : I don't want to use Callisto for a single requirement.

enter image description here

Flyout usercontrol. (ExportTypes.xaml)

<Border BorderThickness="2" BorderBrush="#1789E6" Background="#D1E7FA" Width="230">
    <StackPanel VerticalAlignment="Bottom">
        <Grid x:Name="grdPdf" Tapped="grdExportType_Tapped">
            <TextBlock Text="PDF" FontSize="20" />
        </Grid>
        <Grid x:Name="grdOpenSpreadsheet" Tapped="grdExportType_Tapped">
            <TextBlock Text="Open Office Spreadsheet" FontSize="20"/>
        </Grid>
        <Grid x:Name="grdMsExcel" Tapped="grdExportType_Tapped">
            <TextBlock Text="Microsoft Excel" FontSize="20"/>
        </Grid>
        <Grid x:Name="grdMsWord" Tapped="grdExportType_Tapped">
            <TextBlock Text="Microsoft Word" FontSize="20"/>
        </Grid>
        <Grid x:Name="grdOpenDoc" Tapped="grdExportType_Tapped">
            <TextBlock Text="Open Office Document" FontSize="20"/>
        </Grid>
        <Grid x:Name="grdHtml" Tapped="grdExportType_Tapped">
            <TextBlock Text="HTML" FontSize="20"/>
        </Grid>
        <Grid x:Name="grdRtf" Tapped="grdExportType_Tapped">
            <TextBlock Text="RTF" FontSize="20"/>
        </Grid>
        <Grid x:Name="grdPlainText" Tapped="grdExportType_Tapped">
            <TextBlock Text="Plain Text" FontSize="20"/>
        </Grid>
        <Grid x:Name="grdJson" Tapped="grdExportType_Tapped">
            <TextBlock Text="JSON" FontSize="20"/>
        </Grid>
        <Grid x:Name="grdMsPowerPoint" Tapped="grdExportType_Tapped">
            <TextBlock Text="Microsoft PowerPoint" FontSize="20"/>
        </Grid>
    </StackPanel>
</Border>

Download button click event in MainPage.xaml.cs

private void btnDownload_Click(object sender, RoutedEventArgs e)
{
    var ucExportTypes = new ExportTypes();
    var flyout = new Popup();
    var windowBounds = Window.Current.Bounds;
    var rootVisual = Window.Current.Content;

    var gt = btnDownload.TransformToVisual(rootVisual);
    var absolutePosition = gt.TransformPoint(new Point(0, 0));

    flyout.IsLightDismissEnabled = true;
    flyout.VerticalOffset = absolutePosition.Y - 150 - 10;
    flyout.HorizontalOffset = absolutePosition.X + 20;
    flyout.Child = ucExportTypes;
    flyout.IsOpen = true;
}

3条回答
Explosion°爆炸
2楼-- · 2019-06-26 07:06

Your vertical offset issue can be solved if you have a container, and you grow it but from bottom, up. The designHeight of the entire user control must be the one in which you have the maximum number of elements (10, in your case). The user control will have the VerticalAlignment set to Bottom so any added elements will force the user control to grow from bottom, up, leaving the bottom border of the user control stationary. That Stackpanel you're using in ExportType.xaml might give you some headaches...

Here is a link that could help you understand what I want to mean. It's about animating a height from bottom, up (you don't need animation, but mainly to get the idea of "bottom, to up"). Read carefully the accepted answer of that question, regarding the requirements of the height.

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-06-26 07:12

Just change it to be an ItemsControl in the Popup that is bound to an ObservableCollection in your View Model. Then when you change what is available (you seem to call it case) then update the collection. The ItemsControl will setup again, and you can re-show the Flyout using the same logic.

Use this http://codepaste.net/erev2v

And code something like this:

new FlyoutHelper().Show(YourFlyout, YourButton);

It should be that easy, to be honest. The only gotcha would only be if the number of items in the list changed while the menu is visible. Other than that, I think you are set.

Best of luck!

查看更多
登录 后发表回答