你知道标签+文本框数据输入布局的更动态的网格吗?

Posted

技术标签:

【中文标题】你知道标签+文本框数据输入布局的更动态的网格吗?【英文标题】: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 社区,并且肯定会投票赞成任何合理的建议。

【问题讨论】:

【参考方案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>

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

【讨论】:

以上是关于你知道标签+文本框数据输入布局的更动态的网格吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Vue.js 以更动态的方式显示复选框

使用网格布局进行表单设计

你不能不知道的前端知识体系

HTMLHTML 注册表单案例 ② ( 表格中的内容设置 | 下拉列表 | 输入文本框 | 复选框 | 文本域 | 图片按钮 | 链接 )

在 VS10 .NET 表单中寻找更动态的设计器 TypeConverter 序列化

使用 jQuery/MySQL 刷新 Textarea