修复了XAML中的定位

本文关键字:定位 XAML | 更新日期: 2023-09-27 18:25:35

我有一个Windows应用商店风格的WPF应用程序,我刚刚添加了搜索。当我单击应用程序栏中的搜索按钮时,我将包含SearchBoxFlyoutPresenter设置为Visible。此按钮位于右下角。它在带键盘的电脑上运行良好,但当虚拟键盘InputPane打开时,我遇到了一个问题。首先,键盘盖住了盒子。当框处于焦点时,我通过检查和调整框的边距来解决这个问题,但当我将页面滚动到最顶部和最底部时,控件开始在页面上移动。这是我的最小代码:

XAML:

<Grid Background="White" x:Name="MainGrid">
    <!-- App Bar with Search button -->
    <AppBar x:Name="BAppBar" VerticalAlignment="Bottom">
        <CommandBar>
            <CommandBar.PrimaryCommands>
                <AppBarButton Icon="Find" Label="Search" Click="Search_Click"/>
            </CommandBar.PrimaryCommands>
        </CommandBar>
    </AppBar>
    <!-- Search button and Close button -->
    <FlyoutPresenter VerticalAlignment="Top" Name="SearchPop" Visibility="Collapsed">
        <StackPanel Orientation="Horizontal">
            <SearchBox Name="Search" GotFocus="Search_Focus" LostFocus="Search_Focus"/>
            <AppBarButton Name="SearchClose" Icon="Cancel" Click="Search_Close" />
        </StackPanel>
    </FlyoutPresenter>
</Grid>

C#:

public partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }
    // Close app bar, show search box, and set margin to bottom of page
    private void Search_Click(object sender, RoutedEventArgs e)
    {
        BAppBar.IsOpen = false;
        SearchPop.Visibility = Windows.UI.Xaml.Visibility.Visible;
        SearchPop.Margin = new Thickness(0, MainGrid.ActualHeight - SearchPop.ActualHeight, 0, 0);
    }
    // Set margin for opening/closing virtual keyboard
    private void Search_Focus(object sender, RoutedEventArgs e)
    {
        Windows.UI.ViewManagement.InputPane.GetForCurrentView().Showing += (s, args) =>
        {
            double flyoutOffset = (int)args.OccludedRect.Height - SearchPop.ActualHeight;
            SearchPop.Margin = new Thickness(0, flyoutOffset, 0, 0);
        };
        Windows.UI.ViewManagement.InputPane.GetForCurrentView().Hiding += (s, args) =>
        {
            SearchPop.Margin = new Thickness(0, MainGrid.ActualHeight - SearchPop.ActualHeight, 0, 0);
        };
    }
    // Close search
    private void Search_Close(object sender, RoutedEventArgs e)
    {
        SearchPop.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
    }
}

我需要的是盒子不受用户在屏幕上滚动的影响。在HTML中,这被称为固定定位。我读到在XAML中它本身是不可能的,但是有一些变通方法。我读过这些MSDN和SO链接,但它们并没有真正的帮助:

http://social.msdn.microsoft.com/Forums/en-US/9779328a-a7cd-447d-a4ac-bcc952083f43/fixed-positioning-in-wpf?forum=wpf

http://social.msdn.microsoft.com/Forums/windowsapps/en-US/7349d01d-dc0e-4e1c-9327-df90e00fbebf/how-to-handle-the-appearance-of-the-onscreen-keyboard?forum=winappswithcsharp

弹出控件随父移动

修复了XAML中的定位

您可以用一种非常简单的方式模拟XAML中的固定行为:

<Grid Background="White" x:Name="MainGrid">
    <ContentControl VerticalAligment="Stretch" HorizontalAligment="Stretch">
    <!--All other visual controls, the float item will be located over all controls    located here, even scrolls viewers-->
    </ContentControl>
    <!-- Float item -->
    <SomeControl>
    <!--The control you want be over in the fixed position, 
        you can set the layout to it, and locate it where you want
        just set the Vertical/Horizontal Aligment, margin, height, width-->
    </SomeControl>
</Grid>

(很抱歉,如果代码样本有一些sintax错误,我已经写了)此外,wpf有一些控件显示在一个层上,而不是其他所有控件,这些元素是上下文菜单、工具提示和装饰器,你也可以尝试它们。

我希望这些想法能有所帮助。