【问题标题】:UserControl containing nested Grids, and exposing Content property of deepest nested gridUserControl 包含嵌套网格,并公开最深嵌套网格的 Content 属性
【发布时间】:2018-07-22 18:18:48
【问题描述】:

我想创建一个自定义用户控件,其中包含两个相互嵌套的网格:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
...

public class VGrid : Grid
{
    public VGrid()
    {
        RowDefinitions.Add(new RowDefinition()
        { Height = GridLength.Auto });

        RowDefinitions.Add(new RowDefinition()
        { Height = new GridLength(1, GridUnitType.Star) });

        RowDefinitions.Add(new RowDefinition()
        { Height = GridLength.Auto });
    }
}

public class HGrid : Grid
{
    public HGrid()
    {
        ColumnDefinitions.Add(new ColumnDefinition()
        { Width = GridLength.Auto });

        ColumnDefinitions.Add(new ColumnDefinition()
        { Width = new GridLength(1, GridUnitType.Star)});

        ColumnDefinitions.Add(new ColumnDefinition()
        { Width = GridLength.Auto });

    }
}

这就是我卡住的地方...如何为每一行创建自定义属性,内部和外部网格的列为相应的子项分配网格的行/列的正确附加属性。

public class NineGrid : HGrid
{
    VGrid inner0;
    VGrid inner1;
    VGrid inner2;

    public NineGrid()
    {
        inner1 = new VGrid();
        inner2 = new VGrid();
        inner3 = new VGrid();

        this.Children.Add(inner1);
        this.Children.Add(inner2);
        this.Children.Add(inner3);
    }
}

但是,这就是我想要的样子:

<local:NineGrid>

    <!-- First Row: Toolbar + Hamburger Button -->
    <local:NineGrid.XY_0_0><Button Content="0,0"/><local:NineGrid.XY_0_0>
    <local:NineGrid.XY_0_1><Button Content="0,1"/><local:NineGrid.XY_0_1>
    <local:NineGrid.XY_0_2><Button Content="0,2"/><local:NineGrid.XY_0_2>

    <!-- Second Row: ContentPage + Left and Right Side Menus -->
    <local:NineGrid.XY_1_0><Frame Name="AFrame0"/><local:NineGrid.XY_1_0>
    <local:NineGrid.XY_1_1><Frame Name="AFrame1"/><local:NineGrid.XY_1_1>
    <local:NineGrid.XY_1_2><Frame Name="AFrame2"/><local:NineGrid.XY_1_2>

    <!-- Third Row: Status Bar + Misc + Settings Button -->
    <local:NineGrid.XY_2_0><Button Content="2,0"/><local:NineGrid.XY_2_0>
    <local:NineGrid.XY_2_1><Button Content="2,1"/><local:NineGrid.XY_2_1>
    <local:NineGrid.XY_2_2><Button Content="2,2"/><local:NineGrid.XY_2_2>

</local:NineGrid>

在 XAML 示例中使用按钮是我将如何使用此自定义控件的玩具示例。

真正的场景是第一行,一个带有左右控件的命令栏,根据窗口或菜单状态的大小出现和消失,第二行带有左右弹出菜单的中心内容,最后一行带有状态行。

有可能吗?如果您将两个网格相互嵌套,然后在其中放入更多还包含网格的内容,那么普通的 XAML 代码就会变得混乱。所以我的想法是创建一个自定义控件,将两个顶级嵌套网格展平成对于我需要的 95% 的情况,一个已经按照我想要的方式设置的控件。问题是如何使用 XAML 填充嵌套网格的自定义控件。

【问题讨论】:

  • 为什么不使用具有 3 行 3 列的单个 Grid?也就是说,很明显,通过嵌套,您要么需要 1 个外部 VGrid 和 3 个内部 HGrid,要么需要 1 个 HGrid 和 3 个 VGrid。
  • ContentPropertyAttribute Class docs.microsoft.com/en-us/uwp/api/… 我在想它应该是一个继承自网格的类,然后在构造函数中创建一个新的网格并将其分配给this.grid的Child,然后执行使用 ContentPropertAttribute 来分配新网格的 children 属性的内部网格而不是外部网格的默认子网格的一些魔法
  • 这是你会反复重复使用的东西吗?还是只有一页?
  • 每页至少使用一次。但是,将 NineGrid 嵌套在 NineGrid 的一个单元中可能会很有趣......
  • @BillMoore 除了 NineGrid 之外,您还需要 HGrid 和 VGrid 吗?

标签: wpf xaml uwp


【解决方案1】:

我能想到的最好的办法就是嵌套 VGrid 和 HGrid 而忘记合并它们:

<Page
    x:Class="junk6.BlankPage2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:junk6"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>
        <Style TargetType="Button">
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="BorderThickness"  Value="2"/>
            <Setter Property="Margin" Value="2"/>
        </Style>
    </Page.Resources>

    <local:VGrid>
        <local:HGrid Grid.Row="0">
            <Button Grid.Column="0" Content="Button0"/>
            <Button Grid.Column="1" Content="Button1"
                 HorizontalAlignment="Stretch"/>
            <Button Grid.Column="2" Content="Button2"/>
        </local:HGrid>

        <local:HGrid Grid.Row="1">
            <Button Grid.Column="0" Content="Buttonc0" 
                VerticalAlignment="Stretch"/>
            <Button Grid.Column="1" Content="Buttonc1" 
                VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
            <Button Grid.Column="2" Content="Buttonc2"  
                VerticalAlignment="Stretch"/>
        </local:HGrid>


        <local:HGrid Grid.Row="2">
            <Button Grid.Column="0" Content="Button0"/>
            <Button Grid.Column="1" Content="Button1" 
                HorizontalAlignment="Stretch"/>
            <Button Grid.Column="2" Content="Button2"/>
        </local:HGrid>

    </local:VGrid>

</Page>


using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace junk6
{

public class VGrid : Grid
{
    public VGrid()
    {
        RowDefinitions.Add(new RowDefinition()
        { Height = GridLength.Auto });

        RowDefinitions.Add(new RowDefinition()
        { Height = new GridLength(1, GridUnitType.Star) });

        RowDefinitions.Add(new RowDefinition()
        { Height = GridLength.Auto });
    }
}

public class HGrid : Grid
{
    public HGrid()
    {
        ColumnDefinitions.Add(new ColumnDefinition()
        { Width = GridLength.Auto });

        ColumnDefinitions.Add(new ColumnDefinition()
        { Width = new GridLength(1, GridUnitType.Star)});

        ColumnDefinitions.Add(new ColumnDefinition()
        { Width = GridLength.Auto });

    }
}

}

也可以反过来嵌套:

<Page
    x:Class="junk6.BlankPage3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:junk6"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>
        <Style TargetType="Button">
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="BorderThickness"  Value="2"/>
            <Setter Property="Margin" Value="2"/>
        </Style>
    </Page.Resources>

    <local:HGrid>
        <local:VGrid Grid.Column="0">
            <Button Grid.Row="0" Content="Button0"/>
            <Button Grid.Row="1" Content="Button1"
               VerticalAlignment="Stretch"/>
            <Button Grid.Row="2" Content="Button2"/>
        </local:VGrid>

        <local:VGrid Grid.Column="1">
            <Button Grid.Row="0" Content="Buttonc0" 
                HorizontalAlignment="Stretch" />
            <Button Grid.Row="1" Content="Buttonc1"
                HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
            <Button Grid.Row="2" Content="Buttonc2" 
                HorizontalAlignment="Stretch" />
        </local:VGrid>


        <local:VGrid Grid.Column="2">
            <Button Grid.Row="0" Content="Button0"/>
            <Button Grid.Row="1" Content="Button1" 
              VerticalAlignment="Stretch"/>
            <Button Grid.Row="2" Content="Button2"/>
        </local:VGrid>

    </local:HGrid>

</Page>

【讨论】:

    【解决方案2】:

    尤里卡!

    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace GridNineExperiment
    {
    
    public class VGrid : Grid
        {
            public VGrid()
            {
                RowDefinitions.Add(new RowDefinition()
                { Height = GridLength.Auto });
    
                RowDefinitions.Add(new RowDefinition()
                { Height = new GridLength(1, GridUnitType.Star) });
    
                RowDefinitions.Add(new RowDefinition()
                { Height = GridLength.Auto });
            }
        }
    
        public class HGrid : Grid
        {
            public HGrid()
            {
                ColumnDefinitions.Add(new ColumnDefinition()
                { Width = GridLength.Auto });
    
                ColumnDefinitions.Add(new ColumnDefinition()
                { Width = new GridLength(1, GridUnitType.Star) });
    
                ColumnDefinitions.Add(new ColumnDefinition()
                { Width = GridLength.Auto });
    
            }
        }
    
        //================================================================
        // NineGrid
        //================================================================
        public class NineGrid : VGrid
        {
            public HGrid inner0;
            public HGrid inner1;
            public HGrid inner2;
    
            public NineGrid()
            {
                inner0 = new HGrid();
                inner1 = new HGrid();
                inner2 = new HGrid();
    
                this.Children.Add(inner0);
                this.Children.Add(inner1);
                this.Children.Add(inner2);
    
                Grid.SetRow(inner1, 0);
                Grid.SetRow(inner1, 1);
                Grid.SetRow(inner2, 2);
            }
    
            //===========================================================
            // (0, 0)
            //===========================================================
            private FrameworkElement private_NG00 = null;
    
            public  FrameworkElement NG00
            {
                get { return private_NG00; }
                set {
                    inner0.Children.Add(value);
                    Grid.SetColumn(value, 0);
                    private_NG00 = value;
                }
            }
    
            //===========================================================
            // (0, 1)
            //===========================================================
            private FrameworkElement private_NG01 = null;
    
            public FrameworkElement NG01
            {
                get { return private_NG01; }
                set
                {
                    inner0.Children.Add(value);
                    Grid.SetColumn(value, 1);
                    private_NG01 = value;
                }
            }
    
            //===========================================================
            // (0, 2)
            //===========================================================
            private FrameworkElement private_NG02 = null;
    
            public FrameworkElement NG02
            {
                get { return private_NG02; }
                set
                {
                    inner0.Children.Add(value);
                    Grid.SetColumn(value, 2);
                    private_NG02 = value;
                }
            }
    
            //===========================================================
            // (1, 0)
            //===========================================================
            private FrameworkElement private_NG10 = null;
    
            public FrameworkElement NG10
            {
                get { return private_NG10; }
                set
                {
                    inner1.Children.Add(value);
                    Grid.SetColumn(value, 0);
                    private_NG10 = value;
                }
            }
    
            //===========================================================
            // (1, 1)
            //===========================================================
            private FrameworkElement private_NG11 = null;
    
            public FrameworkElement NG11
            {
                get { return private_NG11; }
                set
                {
                    inner1.Children.Add(value);
                    Grid.SetColumn(value, 1);
                    private_NG11 = value;
                }
            }
    
            //===========================================================
            // (1, 2)
            //===========================================================
            private FrameworkElement private_NG12 = null;
    
            public FrameworkElement NG12
            {
                get { return private_NG12; }
                set
                {
                    inner1.Children.Add(value);
                    Grid.SetColumn(value, 2);
                    private_NG12 = value;
                }
            }
    
            //===========================================================
            // (2, 0)
            //===========================================================
            private FrameworkElement private_NG20 = null;
    
            public FrameworkElement NG20
            {
                get { return private_NG20; }
                set
                {
                    inner2.Children.Add(value);
                    Grid.SetColumn(value, 0);
                    private_NG20 = value;
                }
            }
    
            //===========================================================
            // (2, 1)
            //===========================================================
            private FrameworkElement private_NG21 = null;
    
            public FrameworkElement NG21
            {
                get { return private_NG21; }
                set
                {
                    inner2.Children.Add(value);
                    Grid.SetColumn(value, 1);
                    private_NG21 = value;
                }
            }
    
            //===========================================================
            // (2, 2)
            //===========================================================
            private FrameworkElement private_NG22 = null;
    
            public FrameworkElement NG22
            {
                get { return private_NG22; }
                set
                {
                    inner2.Children.Add(value);
                    Grid.SetColumn(value, 2);
                    private_NG22 = value;
                }
            }
    
        } // Class
    
    }
    
    
    <Page
        x:Class="GridNineExperiment.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:GridNineExperiment"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Page.Resources>
            <Style TargetType="Button">
                <Setter Property="BorderBrush" Value="Black"/>
                <Setter Property="BorderThickness"  Value="2"/>
                <Setter Property="Margin" Value="2"/>
            </Style>
        </Page.Resources>
    
        <local:NineGrid>
    
            <!-- ROW 0-->
            <local:NineGrid.NG00>
                <Button Content="Button0"/>
            </local:NineGrid.NG00>
    
            <local:NineGrid.NG01>
                <Button Content="Button1" HorizontalAlignment="Stretch"/>
            </local:NineGrid.NG01>
    
            <local:NineGrid.NG02>
                <Button Content="Button2"/>
            </local:NineGrid.NG02>
    
            <!-- ROW 1-->
            <local:NineGrid.NG10>
                <Button Content="Buttonc0" VerticalAlignment="Stretch"/>
            </local:NineGrid.NG10>
    
            <local:NineGrid.NG11>
                <Button Content="Buttonc1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
            </local:NineGrid.NG11>
    
            <local:NineGrid.NG12>
                <Button Grid.Column="2" Content="Buttonc2" VerticalAlignment="Stretch"/>
            </local:NineGrid.NG12>
    
            <!-- ROW 2-->
            <local:NineGrid.NG20>
                <Button Content="Button0"/>
            </local:NineGrid.NG20>
    
            <local:NineGrid.NG21>
                <Button Content="Button1" HorizontalAlignment="Stretch"/>
            </local:NineGrid.NG21>
    
            <local:NineGrid.NG22>
                <Button Content="Button2"/>
            </local:NineGrid.NG22>
        </local:NineGrid>
    </Page>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-27
      • 1970-01-01
      • 1970-01-01
      • 2013-03-24
      • 2011-11-18
      • 1970-01-01
      • 2017-11-23
      相关资源
      最近更新 更多