如何创建动态变化的网格?

How to create dynamically changed grid?

一开始我想说的是,我才刚刚开始 Xaml 的冒险,所以如果问题不重要,请谅解。

我要设计一个具有可变布局的用户控件,它由 UWP 的单选按钮控制 - C++Cx 应用程序。 通常,用户控件有 4 种可能的视图/状态。我在图片中显示:

以这种方式构造此控件的最佳方法是什么?可能这很重要,我想将可观察的集合绑定到图片中可见的元素:

集合的元素 0 - 主视图和元素 1-4:较小的侧视图

提前致谢!

我们可以尝试使用用户控件并 VisualState 来实现它。您可以将根网格分成两列,将主视图放入第 0 列,然后将第 1 列分为 6 行和 6 列。

首先,您可以在第二列中添加四个视图,并将它们的可见性设置为折叠。当你想显示第一个只包含主视图的布局时,你可以在 VisualState 中将 MainView.(Grid.ColumnSpan) 的值设置为 2。当你想显示主视图和其他小视图时,你需要将 MainView.(Grid.ColumnSpan) 更改为 1 并且 re-layout 通过更改其行和列来更改这些小视图。例如:

.UserControl.xaml:

<Grid x:Name="RootGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Grid x:Name="MainView" Background="Gray">
        <StackPanel>
            <RadioButton
                x:Name="firstrb"
                Margin="10"
                Click="rb_Click"
                Content="First Layout" />
            <RadioButton
                x:Name="secondrb"
                Margin="10"
                Click="rb_Click"
                Content="Second Layout" />
            <RadioButton
                x:Name="thirdrb"
                Margin="10"
                Click="rb_Click"
                Content="Third Layout" />
            <RadioButton
                x:Name="fourthrb"
                Margin="10"
                Click="rb_Click"
                Content="Fourth Layout" />
        </StackPanel>
    </Grid>
    <Grid x:Name="SideView" Visibility="Collapsed">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <StackPanel
            x:Name="View1"
            Background="Red"
            Visibility="Collapsed" />
        <StackPanel
            x:Name="View2"
            Background="Yellow"
            Visibility="Collapsed" />
        <StackPanel
            x:Name="View3"
            Background="Blue"
            Visibility="Collapsed" />
        <StackPanel
            x:Name="View4"
            Background="Green"
            Visibility="Collapsed" />
    </Grid>

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="FirstLayout">
                <VisualState.Setters>
                    <Setter Target="MainView.(Grid.ColumnSpan)" Value="2" />
                </VisualState.Setters>
            </VisualState>

            <VisualState x:Name="SecondLayout">
                <VisualState.Setters>
                    <Setter Target="MainView.(Grid.Column)" Value="0" />
                    <Setter Target="SideView.(Grid.Column)" Value="1" />
                    <Setter Target="SideView.Visibility" Value="Visible" />
                    <Setter Target="View1.Visibility" Value="Visible" />
                    <Setter Target="View1.(Grid.Row)" Value="0" />
                    <Setter Target="View1.(Grid.RowSpan)" Value="3" />
                    <Setter Target="View1.(Grid.Column)" Value="0" />
                    <Setter Target="View1.(Grid.ColumnSpan)" Value="6" />
                    <Setter Target="View2.Visibility" Value="Visible" />
                    <Setter Target="View2.(Grid.Row)" Value="3" />
                    <Setter Target="View2.(Grid.RowSpan)" Value="3" />
                    <Setter Target="View2.(Grid.Column)" Value="0" />
                    <Setter Target="View2.(Grid.ColumnSpan)" Value="6" />
                </VisualState.Setters>
            </VisualState>

            <VisualState x:Name="ThirdLayout">
                <VisualState.Setters>
                    <Setter Target="MainView.(Grid.Column)" Value="0" />
                    <Setter Target="SideView.(Grid.Column)" Value="1" />
                    <Setter Target="SideView.Visibility" Value="Visible" />
                    <Setter Target="View1.Visibility" Value="Visible" />
                    <Setter Target="View1.(Grid.Row)" Value="0" />
                    <Setter Target="View1.(Grid.RowSpan)" Value="2" />
                    <Setter Target="View1.(Grid.Column)" Value="0" />
                    <Setter Target="View1.(Grid.ColumnSpan)" Value="6" />
                    <Setter Target="View2.Visibility" Value="Visible" />
                    <Setter Target="View2.(Grid.Row)" Value="2" />
                    <Setter Target="View2.(Grid.RowSpan)" Value="2" />
                    <Setter Target="View2.(Grid.Column)" Value="0" />
                    <Setter Target="View2.(Grid.ColumnSpan)" Value="6" />
                    <Setter Target="View3.Visibility" Value="Visible" />
                    <Setter Target="View3.(Grid.Row)" Value="4" />
                    <Setter Target="View3.(Grid.RowSpan)" Value="2" />
                    <Setter Target="View3.(Grid.Column)" Value="0" />
                    <Setter Target="View3.(Grid.ColumnSpan)" Value="6" />
                </VisualState.Setters>
            </VisualState>
            
            <VisualState x:Name="FourthLayout">
                <VisualState.Setters>
                    <Setter Target="MainView.(Grid.Column)" Value="0" />
                    <Setter Target="SideView.(Grid.Column)" Value="1" />
                    <Setter Target="SideView.Visibility" Value="Visible" />
                    <Setter Target="View1.Visibility" Value="Visible" />
                    <Setter Target="View1.(Grid.Row)" Value="0" />
                    <Setter Target="View1.(Grid.RowSpan)" Value="3" />
                    <Setter Target="View1.(Grid.Column)" Value="0" />
                    <Setter Target="View1.(Grid.ColumnSpan)" Value="3" />
                    <Setter Target="View2.Visibility" Value="Visible" />
                    <Setter Target="View2.(Grid.Row)" Value="0" />
                    <Setter Target="View2.(Grid.RowSpan)" Value="3" />
                    <Setter Target="View2.(Grid.Column)" Value="3" />
                    <Setter Target="View2.(Grid.ColumnSpan)" Value="3" />
                    <Setter Target="View3.Visibility" Value="Visible" />
                    <Setter Target="View3.(Grid.Row)" Value="3" />
                    <Setter Target="View3.(Grid.RowSpan)" Value="3" />
                    <Setter Target="View3.(Grid.Column)" Value="0" />
                    <Setter Target="View3.(Grid.ColumnSpan)" Value="3" />
                    <Setter Target="View4.Visibility" Value="Visible" />
                    <Setter Target="View4.(Grid.Row)" Value="3" />
                    <Setter Target="View4.(Grid.RowSpan)" Value="3" />
                    <Setter Target="View4.(Grid.Column)" Value="3" />
                    <Setter Target="View4.(Grid.ColumnSpan)" Value="3" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Grid>

.UserControl.xaml.cpp:

void AppCX::UserControl::rb_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    RadioButton^ rb = (RadioButton^)sender;

    if (rb->Name == "firstrb")
    {
        VisualStateManager::GoToState(this, "FirstLayout", false);
    }

    if (rb->Name == "secondrb")
    {
        VisualStateManager::GoToState(this, "SecondLayout", false);
    }

    if (rb->Name == "thirdrb")
    {
        VisualStateManager::GoToState(this, "ThirdLayout", false);
    }

    if (rb->Name == "fourthrb")
    {
        VisualStateManager::GoToState(this, "FourthLayout", false);
    }
}