【问题标题】:Do yo know of a more dynamic grid for Labels + TextBoxes data entry layouts?你知道标签+文本框数据输入布局的更动态的网格吗?
【发布时间】:2009-06-24 07:34:52
【问题描述】:

我的 LOB 应用有 负载 个屏幕,这些屏幕具有并排的标签列和文本框。

我想要在 Grid 和 WrapPanel 布局之间实现一些东西 - 当页面/窗口足够宽时,标签 + 文本框对重新组织成多个列。想象一下:

窄窗布局:

Label            | TextBox
Looooong Label   | TextBox
Label            | TextBox
Label            | TextBox

宽窗口布局:

Label            | TextBox      | Looooong Label   | TextBox
Label            | TextBox      | Label            | TextBox

使用网格很容易,因为标签列的宽度可以是“自动”...但是随着窗口宽度的增加/减少,很难动态设置列数,因为它需要每个标签上的样式/文本框。

使用 WrapPanel 实现了多列的效果,但是每个 Label 的宽度都不一样。我会更喜欢一个不涉及通过样式或绑定来限制标签​​的所有 Width 属性的解决方案。

您是否知道解决此问题的优雅方法,或者您是否遇到过专门提供此功能的任何开源/3rd 方面板控件?

我尊重 Stack-Overflow 社区,并且肯定会投票赞成任何合理的建议。

【问题讨论】:

    标签: wpf


    【解决方案1】:

    我找到了一个答案,它似乎在提高 XAML 可读性和可维护性方面有几个好处。

    通过为 TextBox 和 Combobox 创建 ControlTemplates,您可以轻松地在列上使用 SharedSizeGroup 建立网格,这有助于保持标签的宽度相同。我创建的控件模板使用逻辑控件的 Tag 属性来确定模板创建的视觉对象中标签的文本。

    考虑以下 XAML,它创建两个文本框,两个文本框都数据绑定到底层业务对象:

    <WrapPanel Orientation="Horizontal" Grid.IsSharedSizeScope="True">
    
        <TextBox Tag="On Hand:"
                         Text="{Binding Path=Product.StockOnHand}"
                         Template="{StaticResource LabeledTextBoxTemplate}"
                         IsReadOnly="True"
                         ToolTip="" />
    
        <TextBox    Tag="On Order:"
                            Text="{Binding Path=Product.StockOnOrder}"
                            Template="{StaticResource LabeledTextBoxTemplate}"
                            IsReadOnly="True"
                            ToolTip="" />
    
    </WrapPanel>
    

    这些框位于 SharedSizeGroup 设置为 true 的包装面板内。这允许网格(由控件模板创建)共享列宽信息。由于文本框位于 WrapPanel 内,因此它们将在换行到下一行之前使用尽可能多的宽度。

    将上述逻辑文本框呈现为网格的 ControlTemplate(和样式)如下:

    <!--Style and ControlTemplates to support aligned, labeled text boxes and combo boxes.-->
    <Style TargetType="Grid"
                 x:Key="LabelledDataGridStyle">
        <Setter Property="Margin"
                        Value="0,0,12,4" />
    </Style>
    
    <Style TargetType="ColumnDefinition"
                 x:Key="LabelingGridThirdColumnStyle">
        <Setter Property="Width"
                        Value="150" />
        <Style.Triggers>
            <DataTrigger  Binding="{Binding Path=ItemWidth,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=WrapPanel,AncestorLevel=1}}"
                                        Value="{x:Null}">
                <Setter Property="Width"
                                Value="Auto" />
                <Setter Property="SharedSizeGroup"
                                Value="C" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
    
    <ControlTemplate TargetType="TextBox" x:Key="LabeledTextBoxTemplate">
        <Grid Style="{StaticResource LabelledDataGridStyle}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="A" Width="Auto" />
                <ColumnDefinition Style="{StaticResource LabelingGridThirdColumnStyle}" />
            </Grid.ColumnDefinitions>
    
            <TextBlock Text="{Binding Path=Tag,RelativeSource={RelativeSource TemplatedParent}}"
                                 VerticalAlignment="Top"
                                 Margin="0,4,8,0"
                                 HorizontalAlignment="Left" />
    
            <TextBox Text="{Binding Path=Text,RelativeSource={RelativeSource TemplatedParent}}"
                        TextAlignment="{Binding Path=TextAlignment,RelativeSource={RelativeSource TemplatedParent}}"
                        Style="{Binding Path=Style,RelativeSource={RelativeSource TemplatedParent}}"
                        Background="{Binding Path=Background,RelativeSource={RelativeSource TemplatedParent}}"
                        ToolTip="{Binding Path=ToolTip,RelativeSource={RelativeSource TemplatedParent}}"
                        ContextMenu="{Binding Path=ContextMenu,RelativeSource={RelativeSource TemplatedParent}}"
                        MinWidth="100"
                        Grid.Column="1" />
    
        </Grid>
    
    </ControlTemplate>
    

    它并不完美(完成这项工作的面板控件本来是理想的),但为了快速修复,这很好用。

    【讨论】:

      猜你喜欢
      • 2023-04-04
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 2010-10-31
      • 1970-01-01
      相关资源
      最近更新 更多