UserControl包含嵌套的网格,并暴露最深嵌套网格的内容属性

时间:2018-02-12 14:34:48

标签: wpf xaml uwp

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

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填充嵌套网格的自定义控件。

2 个答案:

答案 0 :(得分:0)

我能想到的最好的就是嵌套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>

答案 1 :(得分:0)

尤里卡!

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>