【问题标题】:WPF - Best Practice for the run-of-the-mill [Label:Input] ControlWPF - 普通 [标签:输入] 控件的最佳实践
【发布时间】:2009-06-19 14:37:43
【问题描述】:

我想知道,这是在 WPF 中获得众所周知的标签输入 [或输出,无关紧要] 组合的最好和最快的方法。它是一个简单的任务,想想“对象”ME的快速输出:


姓名 - 克里斯蒂安

年龄 - 28 岁

心情 - 好


我知道,我可以将 Grid 与 TextBlocks 一起使用。但老实说,“短”的 XAML 有将近半页长(每个标签上的 RowDefinitions、ColDefs、Grid.Col)

另一种方法,使用三个 StackPanels(水平)和一个垂直似乎也有点愚蠢。在这种情况下,我必须给每个标签一个固定的宽度,以使缩进正确。而且它只是“感觉”不对。

因此,鉴于上述情况,您有一个具有 3-6 个属性的自定义对象,您只想将其作为只读转储到您的 GUI,您将如何做(在 WPF 中,Silverlight 也是,如果您真的有心情:)。

当然,我可以为此编写一个用户控件。但是为什么要重新发明轮子,如果它可能已经存在的话......

最后,为了进一步说明,我刚刚在现实生活中创建的示例也是本文发布的原因:

      <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Log Count"  Width="100"/>
            <TextBlock Text="{Binding LastLogRun.LogMessageCount}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Start Time" Width="100"/>
            <TextBlock Text="{Binding LastLogRun.StartTime}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="End Time" Width="100"/>
            <TextBlock Text="{Binding LastLogRun.EndTime}"/>
        </StackPanel>
    </StackPanel>

【问题讨论】:

  • 您似乎要求两件事“最佳/最佳实践”和“最快/快速输出/转储”。你想要哪一个? Bryan A. 为您提供了一个快速的解决方案,Joe W. 为您提供了一个很好的格式化解决方案,您在问题中忽略了它......
  • 是的,你是对的,这不是最好的问题。我认为 Bryan A. 答案尽可能短,我喜欢它用于真正快速和肮脏的东西而无需格式化。用户控制方法也非常好,也许它得到了一点点投票。谢谢大家的想法...
  • 我个人倾向于为此使用网格,但您似乎要求最短的 XAML。如果你要做很多事情或者你想提高性能,我会使用 ListView 或 ListBox 制作一个用户控件。

标签: wpf text controls label


【解决方案1】:

您可以使用共享大小组来获得两个排列整齐的列的自动调整大小的网格行为,同时仍然能够将复杂性提取到 UserControl 中。

下面是一个使用 LabeledEdit 控件的示例,它可以满足您的需求。复杂性已全部被考虑到 UserControl 中,您需要做的就是记住在 StackPanel 上设置 Grid.IsSharedSizeScope:

<Window x:Class="WpfApplication5.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication5"
        Name="Self" Title="Window1" Height="300" Width="300">
    <StackPanel Grid.IsSharedSizeScope="True">
        <local:LabeledEdit Label="Name"/>
        <local:LabeledEdit Label="Age" Text="28"/>
        <!-- and with databinding... -->
        <local:LabeledEdit Label="Width"
                           Text="{Binding Width, ElementName=Self}"/>
        <local:LabeledEdit Label="Height"
                           Text="{Binding Height, ElementName=Self}"/>
    </StackPanel>
</Window>

这里是 UserControl 的源代码。 LabeledEdit.xaml:

<UserControl x:Class="WpfApplication5.LabeledEdit"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Name="Self">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" SharedSizeGroup="LabeledEdit_Labels"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Content="{Binding Label, ElementName=Self}"/>
        <TextBox Grid.Column="1" Text="{Binding Text, ElementName=Self}"/>
    </Grid>
</UserControl>

LabeledEdit.xaml.cs:

using System.Windows;

namespace WpfApplication5
{
    public partial class LabeledEdit
    {
        public static readonly DependencyProperty LabelProperty =
            DependencyProperty.Register("Label", typeof(object), typeof(LabeledEdit));
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(LabeledEdit),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public LabeledEdit()
        {
            InitializeComponent();
        }

        public object Label
        {
            get { return GetValue(LabelProperty); }
            set { SetValue(LabelProperty, value); }
        }
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
    }
}

【讨论】:

    【解决方案2】:

    如果您使用的是 3.5sp1,则可以在绑定中使用 StringFormat。像这样的东西应该可以工作......

    <TextBlock Text="{Binding LastLogRun.LogMessageCount, StringFormat={}Log Count - {0}}" />
    

    【讨论】:

      【解决方案3】:

      也许您应该重新考虑您的 UI。为什么要将标签 - 文本框放在同一行上?这太浪费空间了。

      为什么不用标签 over texbox?然后你就有了一个简单的 UI 简单的 XAML:

      <StackPanel Orientation="Vertical">
        <TextBlock>Name</TextBlock>
        <TextBox />
        <TextBlock>Age</TextBlock>
        <TextBox />
        <TextBlock>Mood</TextBlock>
        <TextBox />
      </StackPanel>
      

      为您的 TextBlocks 添加一些样式,您就拥有了一个漂亮、干净的 UI,几乎没有重复。

      【讨论】:

      • 你为什么要指责 OP 浪费屏幕空间,而你的方法浪费得更多?想一想:使用 OP 的方法,“名称”标签占用 42x26 = 1092 像素。使用您的方法,相同的标签是屏幕的整个宽度,所以在我的显示器上,即使我通过设置 Padding=0 让您领先,您的标签也需要 1440x16 = 23040 像素。您的布局是一个合理的选择,但不要自欺欺人地认为这样会减少对房地产的浪费。
      • Randolpho 的解决方案不错,不是因为它占用的屏幕空间少,而是因为它更容易国际化。通过将 Label 放在 TextBox 上方,间距确实会发生变化,并且标签的长度会因不同的语言而变化。
      【解决方案4】:

      silverlight toolkit 有一个很酷的 DataForm 控件!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-23
        • 2015-09-16
        • 2018-10-14
        • 2012-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多