Как применить макет Grid к вложенным дочерним элементам? - PullRequest
0 голосов
/ 30 апреля 2020

Я почесал голову над этим уже несколько дней. Я пытаюсь создать UserControl (s), которые позволят мне упростить процесс создания форм ввода / вывода. Во многих формах мне нужно что-то со структурой, такой как это:

<Grid>
   <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto">
      <ColumnDefinition Width="*">
   </Grid.ColumnDefinitions>

   <Grid.RowDefinitions>
      <RowDefinition>
      <RowDefinition>
      <RowDefinition>          
      ...
   </Grid.ColumnDefinitions>

   <TextBlock Grid.Column="0" Grid.Row="0" Text="..."/>
   <TextBox Grid.Column="1" Grid.Row="0" Text="..."/>

   <TextBlock Grid.Column="0" Grid.Row="1" Text="..."/>
   <TextBox Grid.Column="1" Grid.Row="1" Text="..."/>

   <TextBlock Grid.Column="0" Grid.Row="2" Text="..."/>
   <TextBox Grid.Column="1" Grid.Row="2" Text="..."/>
   ...

<Grid>

Я хотел бы написать что-то вроде этого:

<mycontrols:ContainerControl>
   <mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}">
   <mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}">
   <mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}">
   <mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}">
</mycontrols:ContainerControl>

XAML RowControl будет просто стиль TextBlock и TextBox на мой вкус:

   <TextBlock Text="{Binding Label}"/>
   <TextBlock Text="{Binding Text}"/>

Как я понимаю, есть несколько проблем с этим:

1.- Для того, чтобы элемент зависит от макета сетки, он должен быть непосредственным потомком этой сетки.

2.- Количество строк произвольно. В Grid вам нужно указать каждое определение строки.

Если бы я мог каким-то образом настроить расположение Grid не только на непосредственных, но и на вложенных, я думаю, я мог бы сделать это. Я также готов решить это с другим подходом, если вы можете придумать один.

Ожидаемое поведение finally представляет собой смесь StackPanel и Grid, а именно:

~ Можно добавить произвольное количество элементов без определения строк (просто сложите их в стек) ,

~ Контейнер разделен на два столбца: первый принимает размер самого большого элемента (auto), а второй - оставшуюся доступную ширину (*).

All помощь приветствуется! Заранее спасибо:)

1 Ответ

1 голос
/ 30 апреля 2020

Возможно, вы сможете использовать ColumnDefinition.SharedSizeGroup и прикрепленное свойство Grid.IsSharedSizeScope. Попробуйте что-то вроде этого:

<UserControl x:Class="CSharpTest.RowControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" SharedSizeGroup="RowLabel"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Text="{Binding Label}"/>
        <TextBlock Text="{Binding Text}" Grid.Column="1"/>
    </Grid>
</UserControl>

А затем использовать его:

<mycontrols:ContainerControl Grid.IsSharedSizeScope="True">
    <mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}"/>
    <mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}"/>
    <mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}"/>
    <mycontrols:RowControl Label="Some label" Text="{Binding SomeProperty}"/>
</mycontrols:ContainerControl>

mycontrols:ContainerControl может быть контейнер любого типа (например, StackPanel, UniformGrid, et c).

В приведенном выше примере первый столбец каждого RowControl Grid будет равномерным (все они будут расти, чтобы вместить наибольшее значение Label). В зависимости от того, что вам нужно, вам также может понадобиться установить SharedSizeGroup во втором столбце (в другое значение , что-то вроде «RowText»).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...