在DataTemplate Stretch中创建最后一个TextBox

时间:2011-09-02 17:55:45

标签: wpf datatemplate

我有一个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>

我希望datatemplate中的最后一个Textbox用尽剩余的空间,但我尝试过的任何工作都没有。如何让这个不合作的TextBox伸展?

编辑:删除了文本框中的高度属性。

4 个答案:

答案 0 :(得分:2)

使用DockPanel将网格更改为LastChildFill="true" 然后,您可以删除所有Margin并让WPF自动执行布局。

答案 1 :(得分:2)

使用<DockPanel>代替<Grid>

DockPanel中的最后一项使用剩余空间。

答案 2 :(得分:2)

通常,我会将<Grid.RowDefinitions><Grid.ColumnDefinitions>与星号大小*结合使用,而不是此类布局的边距。

更新1:(为清晰起见,已删除)

更新2:当我在这样的情况下结束时,我无法弄清楚应用绑定或模板的位置,我尝试备份并以不同方式查看问题。我几乎总是把它带回MVVM模式。在这种情况下,您的Model是您的EventHistory对象。您的ViewModel有一个ObservableCollection<EventHistory>。而您的View只是绑定到该集合。所以,得到这样的东西:

enter image description here

您可以在View中使用类似的内容:

<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>

这很好 - 因为这是你想要实现的目标。屏幕底部的2个标签和文本框上的绑定不必是任何数据模板的一部分。它们是视图的一部分(屏幕截图中红色边框内的所有内容)。所有调整大小的工作和一切都很好。如果你真的想把事情转移到DataTemplate中,那很可能,但这在这一点上看起来更自然。

注意:创建视图(红色边框内的区域)后,我将其托管在主窗口中,根据您的屏幕截图将右侧区域留在右侧。我还采用了网格分割器,星形大小调整和边距等一些自由,因此在保持图像比例的同时,所有可用空间占用了所有空间。

希望这有帮助!

答案 3 :(得分:0)

我的第一个答案对我的吸收有点慢。在意识到你之后我不认为这种方法是正确的。此外,我认为您在使用DataTemplates后无法轻松实现目标。但是,我认为你有几个选择:

  1. 检查Prism,因为擅长构建复合应用程序。但是,对于这个问题,似乎过度杀戮。因此,更直接的方法可能是......
  2. 为您拥有的每个单独的详细信息视图构建自定义控件,然后根据需要编写一些自定义逻辑以加载每个视图。你可以这样设置......
  3. 您的主网格和您的详细信息视图主机(即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();
    

    每个自定义控件都必须使用星号大小等来使布局看起来正确 - 这就是您对问题的追求。显然,仍然需要完成大量的连线。

    这应该会给你你所追求的。对不起第一个答案的复出!