Сделайте последний TextBox в DataTemplate Stretch - PullRequest
0 голосов
/ 02 сентября 2011

У меня есть ItemsControl:

<Border Grid.Row="1" Margin="20" BorderBrush="AliceBlue" BorderThickness="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
   <ItemsControl Margin="10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding SelectedEventHistoryEntryCollection}" ItemTemplateSelector="{StaticResource computerEventHistoryDataTemplateSelector}"/>
</Border>

С некоторыми табличками данных. Я тестирую первый шаблон:

<DataTemplate x:Key="DetailsDataTemplate">
        <Grid>
            <Label Width="150" HorizontalAlignment="Left" VerticalAlignment="Top" Content="{x:Static resx:Resources.Label_ServiceDept}"/>
            <TextBox Margin="110,0,0,0" Width="200" IsReadOnly="True" Text="{Binding ServiceDepartment}" VerticalAlignment="Top" HorizontalAlignment="Left"/>

            <Label Width="150" Margin="0,40,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Content="{x:Static resx:Resources.Label_SLA}"/>
            <TextBox Margin="110,40,0,0" Width="200" IsReadOnly="True" Text="{Binding SLA}" VerticalAlignment="Top" HorizontalAlignment="Left"/>

            <Label Width="150" Margin="0,80,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Content="{x:Static resx:Resources.Label_Details}"/>
            <TextBox Margin="110,80,10,10" IsReadOnly="True" TextWrapping="Wrap" Text="{Binding Details}"/>
        </Grid>
    </DataTemplate>

Я бы хотел, чтобы последнее текстовое поле в табличке данных использовало оставшееся место, но все, что я пробовал, работает. Как мне растянуть этот неработоспособный TextBox?

Редактировать: Удалено свойство высоты в текстовом поле.

Ответы [ 4 ]

2 голосов
/ 02 сентября 2011

Используйте <DockPanel> вместо <Grid>.

Последний элемент в DockPanel использует оставшееся пространство.

2 голосов
/ 02 сентября 2011

Как правило, я использую <Grid.RowDefinitions> и <Grid.ColumnDefinitions> в сочетании со звездообразным размером * вместо полей для этого типа макета.

ОБНОВЛЕНИЕ 1: (удалено для ясности)

ОБНОВЛЕНИЕ 2: Когда я попадаю в такие ситуации, когда не могу понять, где применить привязку или шаблон, я пытаюсь выполнить резервное копирование и посмотреть на проблему по-другому. Я почти всегда возвращаюсь к шаблону MVVM. В этом случае ваша Модель является вашим объектом EventHistory. Ваша ViewModel имеет ObservableCollection<EventHistory>. И ваш взгляд просто привязан к этой коллекции. Итак, чтобы получить что-то вроде этого:

enter image description here

Вы бы использовали что-то подобное для своего просмотра:

<Grid>

    <Grid.RowDefinitions>
        <RowDefinition Height="1*" />
        <RowDefinition Height="8" />
        <RowDefinition Height="1.5*" />
    </Grid.RowDefinitions>

    <DataGrid Grid.Row="0" AutoGenerateColumns="True" 
                ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" 
                HorizontalGridLinesBrush="DarkGray" VerticalGridLinesBrush="DarkGray" />

    <GridSplitter Grid.Row="1" 
                    Background="Transparent"
                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch"   />

    <Border Grid.Row="2" BorderBrush="DarkGray" BorderThickness="1" CornerRadius="3" Padding="8">

        <Grid>

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

            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>

            <Label Grid.Row="0" Grid.Column="0" Content="Status" />
            <TextBox Grid.Row="0" Grid.Column="1" Margin="0,0,0,8" Text="{Binding Path=Status}" />

            <Label Grid.Row="1" Grid.Column="0" Content="Detailed Description" />
            <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}" />

        </Grid>
    </Border>
</Grid>

И это прекрасно - потому что это то, чего вы пытаетесь достичь. Привязки к двум меткам и текстовым полям внизу экрана не обязательно должны быть частью какого-либо шаблона данных. Они являются частью вида (все, что внутри красной границы на скриншоте). Все изменения размера работает, и все хорошо. Если вы действительно хотите перенести вещи в DataTemplate, это возможно, но на данный момент это кажется более естественным.

ПРИМЕЧАНИЕ. После создания вида (область внутри красной рамки) я разместил его в главном окне, оставив область справа, как показано на скриншоте. Я также взял несколько привилегий с разветвителем сетки, изменением размеров звезд и полями, чтобы вещи занимали все доступное пространство при сохранении изображенных пропорций.

Надеюсь, это поможет!

2 голосов
/ 02 сентября 2011

Измените сетку на DockPanel с помощью LastChildFill="true".
Затем можно избавиться от всех Margin с и позволить WPF автоматически делать макет.

0 голосов
/ 07 сентября 2011

Я немного затормозил с первым ответом.После осознания того, кем вы были после, я не думаю, что такой подход был правильным.Кроме того, я не думаю, что вы можете легко достичь того, что вы после использования DataTemplates.Тем не менее, я думаю, у вас есть несколько вариантов:

  1. Проверка на Prism , поскольку она хороша в таких вещах, как создание составных приложений.Тем не менее, похоже, что WAY излишне для этой проблемы.Таким образом, более прямой подход может быть ...
  2. Создайте пользовательские элементы управления для каждого отдельного подробного представления, а затем напишите некоторую пользовательскую логику для загрузки каждого представления по мере необходимости.Вы бы настроили его следующим образом ...

Ваша основная сетка и узел просмотра подробностей (т.е. ContentControl) будут настроены примерно так:

<Grid Background="Transparent">

    <Grid.RowDefinitions>
        <RowDefinition Height="1*" />
        <RowDefinition Height="8" />
        <RowDefinition Height="1.5*" />
    </Grid.RowDefinitions>

    <DataGrid Grid.Row="0" />

    <GridSplitter Grid.Row="1" Background="Transparent"
                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  />

    <Border Grid.Row="2" BorderBrush="DarkGray" BorderThickness="1" CornerRadius="3" Padding="8">
        <ContentControl Grid.Row="2" x:Name="myContent" />            
    </Border>

</Grid>

Икаждый из ваших пользовательских элементов управления для ваших отдельных подробных видов будет настроен примерно так:

<UserControl x:Class="WpfApplication1.CustomUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="Status" />
        <Label Grid.Row="1" Grid.Column="0" Content="Description" />

        <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Status}" />
        <TextBox Grid.Row="1" Grid.Column="1" TextWrapping="Wrap" Text="{Binding Description}" />

    </Grid>
</UserControl>

Во время выполнения строки выбирается в вашей DataGrid, вам придется загрузить правильный пользовательский элемент управления с некоторым кодомнапример:

myContent.Content = new CustomUserControl();

Каждый из ваших пользовательских элементов управления должен будет использовать размеры звездочек и т. д., чтобы макеты выглядели правильно - это то, что вы искали в своем вопросе.Очевидно, есть еще много проволочек, которые нужно сделать.

Это должно дать вам то, что вы ищете.Извините за бега на первый ответ!

...