【问题标题】:How to show the grid on full page in UWP?如何在 UWP 中全页显示网格?
【发布时间】:2023-12-05 04:52:02
【问题描述】:

我正在为 UWP 使用同步融合控件。我在他们的示例应用程序中看到的其中一项功能是在整页上显示数据网格。

类似的东西

点击后页面是这样的

我很确定这不是应用程序的完整模式视图。单击按钮后,它会隐藏导航抽屉和左侧面板。

有人可以告诉它怎么做吗? 提前致谢。

【问题讨论】:

    标签: xaml datagrid fullscreen uwp-xaml syncfusion


    【解决方案1】:

    我对 Syncfusion 具体了解不多,但我可以大致描述一下如何实现它!这似乎是 Navigation ViewMaster/Details 导航设计模式(我将两者链接到各自的文档页面)。无论哪种方式,设计模式通常具有以下结构:

    • 顶框
    • 首页
    • SplitView(或 NavigationView)
    • 框架
    • 内容页面
    • 内容

    基本上,数据网格通常位于页面上。该页面显示在 SplitView 或 NavigationView 的内容区域中的框架中,该框架位于*页面上,该页面直接显示在应用窗口的*框架中。

    在导航抽屉上显示数据网格的“弹出”效果可能是一些巧妙的技巧,用于处理子页面及其显示的框架。所以,让我们看看这是如何做到的鉴于以上导航设计模式的结构信息,可以实现效果。

    数据网格本身应该放置在它自己的页面上,我们假设在下面的代码示例中称为“DataGridPage”(请注意,为清楚起见,页面的属性已被省略):

    <Page>
        <!-- The data grid, or whatever content here -->
    </Page>
    

    我们实际上是在上面列出的列表中添加了两个层;内容页面上有一个框架,该框架中有一个页面,上面有数据网格。因此,您在上面列表中的“内容页面”如下所示:

    <Page>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition >
                <RowDefinition Height="*"></RowDefinition >
            </Grid.RowDefinitions>
    
            <Grid Grid.Row="0">
                <!-- The bread-crumb, search box, and pop-out button are all in here -->
            </Grid>
    
            <Grid Grid.Row="1">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"></ColumnDefinition>
                    <ColumnDefinition Width="*"></ColumnDefinition>
                </Grid.ColumnDefinitions>
    
                <Grid Grid.Column="0">
                    <!-- The "left panel" here -->
                </Grid>
    
                <Frame Name="MyFrame"
                       Grid.Column="1"></Frame>
        </Grid>
    </Page>
    

    然后在“内容页面”的构造函数中(我假设是 C#,但 VB 的逻辑相同):

    public ContentPage()
    {
        this.InitializeComponent();
    
        // You are telling the frame to display your page with the data grid on it.
        // If you don't ever issue a different "Frame.Navigate" statement on this page,
        //    then it will statically display your data grid as if it was on the same
        //    page.
        this.MyFrame.Navigate(typeof(DataGridPage));
    }
    

    现在,我不知道汉堡菜单是如何实现的(“导航抽屉”),有几种实现方法,我猜它是Syncfucsion为您提供的控件......因此,我将跳过尝试写出上面列表中的“首页”的样子(尽管如果您愿意,我可以在后续帖子中详细介绍一种在没有 Syncfusion 的情况下实现该功能的解决方案)。这里最重要的是,它在它的某处有一个显示“ContentPage”的框架(如上所述,它包含左侧面板和数据网格页面的显示)。

    在 UWP 应用的顶层,运行应用的窗口包含一个框架,该框架本身显示“首页”。需要注意这一点,因为它对于这种“弹出”效果如何发挥作用至关重要。

    在您的“内容页面”上,处理页面右上角“弹出”按钮的“点击”事件。在该事件处理程序中,您将获取您的数据网格页面,并将其显示在顶部框架(直接在应用程序窗口内部)而不是“首页”(它当前正在显示)。

    这背后的机制有点棘手,因为您正在处理“内容页面”上的事件(单击“弹出”按钮),但您需要获取对父页面框架的引用显示在(而不是显示内容页面的框架中)。

    解决方案是编写自定义事件。这个想法是每当单击“弹出”按钮时触发此自定义事件,然后“首页”响应该事件,要求其父框架(“顶部框架”)显示数据网格页面。

    Here 是对事件的冗长(并且可能是压倒性的)概述。但是您需要的代码如下所示。在您的“内容页面”上:

    <!-- Other attributes omitted -->
    <Button Name="PopOutButton"
            Click="PopOutButton_Click">
    

    然后在“内容页面”的代码中:

    public sealed partial class ContentPage : Page
    {
        // This is the declaration for your custom event.
        public delegate void PopOutRequestedHandler(object sender, PopOutRequestedEventArgs e);
        public event PopOutRequestedHandler PopOutRequested;
    
        private void RequestPopOut()
        {
            // Ensure that something is listening to the event.
            if (this.PopOutRequested!= null)
            {
                // Create the args, and call the listening event handlers.
                PopOutRequestedEventArgs args = new PopOutRequestedEventArgs();
                this.PopOutRequested(this, args);
            }
        }
    
        public void PopOutButton_Click(object sender, RoutedEventArgs e)
        {
            // Any animation logic you want goes here.
    
            this.RequestPopOut();
        }
    }
    

    您可以定义一个类PopOutRequestedEventArgs 以包含您想在事件中传递的任何属性。对于基本实现,没有一个是绝对必要的。

    现在,在您的“首页”上,您需要订阅该活动。在首页上框架的“导航”事件处理程序中执行此操作。所以你在首页的某个地方有这个:

    <Frame Name="NavFrame"
           Navigated="NavFrame_Navigated"></Frame>
    

    然后在您的“首页”代码中,您有:

    private void NavFrame_Navigated(object sender, NavigationEventArgs e)
    {
        if (e.Content is ContentPage page)
        {
            page.PopOutRequested += this.ContentPage_RequestedPopOut;
        }
    }
    
    private void ContentPage_RequestedPopOut(object sender, PopOutRequestedEventArgs e)
    {
        // This tells the frame this page (the "Top Page") is in, to
        //    instead display the data grid page.
        this.Frame.Navigate(typeof(DataGridPage));
    }
    

    简而言之,这就是效果。要使页面再次“关闭”,只需在数据网格页面上放置一个按钮(当页面显示在“内容页面”的框架中时,您可以隐藏该按钮),并处理其 Click 事件。在这种情况下,请求框架导航回“内容页面”。因此,在某处的数据网格页面上,您可以在“内容页面”上使用与上面详述的按钮相同的按钮,并在其事件处理程序中放置:

    this.Frame.Navigate(typeof(ContentPage));
    

    现在,重要的是您只允许在“顶部框架”中显示“数据网格页面”时单击按钮,因为该代码引用了页面显示的框架在它运行时......它不是绝对参考。如果在“内容页面”的框架中显示“数据网格页面”时调用该代码,将会得到一些意想不到的结果。

    至于在关闭数据网格的“弹出”视图时导航回“首页”的状态,您可以通过“NavigationEventArgs”来完成。将“Top page”的状态(例如其上的框架正在显示“Content page”的事实)存储在您自己的类中(我们在这里将其称为“NavArgs”),然后将其作为参数传递给导航语句:

    // Create an instance of the args class, and store your state info.
    NavArgs navArgs = new NavArgs();
    this.Frame.Navigate(typeof(DataGridPage), navArgs);
    

    您可以将“navArgs”存储在数据网格页面上,然后在退出“弹出”视图并导航回“顶部框架”中的“首页”时,同样将它们传递给Frame.Navigate() 来电。

    它有点彻底(尽管仍然掩盖了很多概念),并且它只是实现该功能的一种可能方式,但希望它有所帮助!

    【讨论】:

    • 嗯,这也有很多详细的解释。谢谢你。我要试试这个。所以基本上你所说的是我们有两个不同的页面,一个是菜单(不是导航抽屉)和右侧的内容,另一个是只有数据网格。我们只是在它们之间导航,按钮单击事件是两个页面中常见的自定义事件。你是这个意思吗?
    • 是的,在两页上。一个有菜单(不是抽屉式导航)和右侧的内容,另一个只有数据网格。您正在页面之间导航,将刚刚的数据网格页面交换为另一个页面。您将其换入哪个框架,决定了它“弹出”的内容。如果您将数据网格页面换成另一个页面,那么它将“弹出”在左侧面板上,而不是导航抽屉。实际上还有第三个*页面,其中包含导航抽屉。您必须为该页面交换数据网格页面,以便它也“弹出”在导航抽屉上。
    【解决方案2】:

    您可以使用属性 GridColumnSizer.Star 在整页中显示网格。

    在 GridColumnSizer.Star 类型中,可用的网格宽度被划分为大小相等的区域,并且为每一列设置划分的宽度。当网格中有三列时,总空间除以三,该值分配给列的宽度。
    您可以从以下链接获取有关 ColumnSizing 的更多详细信息。
    https://help.syncfusion.com/uwp/sfdatagrid/columns#column-sizing

    问候,
    沙迪亚塔南

    【讨论】: