【问题标题】:WPF Label to TextBoxWPF 标签到文本框
【发布时间】:2011-05-22 08:41:58
【问题描述】:

在 WPF 中使用 TextBox 显示文本标签(例如“名称”)的最佳做法是什么? 我想要文本框上方的标签“名称”和许多类似的标签/文本框。 我应该将 Label/TextBox 对放入垂直 StackPanel 中吗?

有没有更简单的解决方案?

【问题讨论】:

    标签: c# .net wpf


    【解决方案1】:

    这是一个可以做到这一点的控件:

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    public class KeyValueControl : Control
    {
        public static readonly DependencyProperty KeyProperty = DependencyProperty.Register(
            "Key",
            typeof(string),
            typeof(KeyValueControl),
            new PropertyMetadata(default(string)));
    
        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
            "Value",
            typeof(object),
            typeof(KeyValueControl),
            new FrameworkPropertyMetadata
            {
                DefaultValue = null,
                BindsTwoWayByDefault = true,
                DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
            });
    
        static KeyValueControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(KeyValueControl), new FrameworkPropertyMetadata(typeof(KeyValueControl)));
        }
    
        public string Key
        {
            get
            {
                return (string)GetValue(KeyProperty);
            }
            set
            {
                SetValue(KeyProperty, value);
            }
        }
    
        public object Value
        {
            get
            {
                return GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
            }
        }
    }
    

    风格:

    <Style TargetType="{x:Type local:KeyValueControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:KeyValueControl}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Key, RelativeSource={RelativeSource TemplatedParent}}"/>
                        <TextBox Grid.Column="1" Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    用法(创建属性网格):

    <ItemsControl>
        <customControls:KeyValueControl Key="First" Value="{Binding Value1}" />
        <customControls:KeyValueControl Key="Second" Value="{Binding Value2}" />
        <customControls:KeyValueControl Key="Last" Value="{Binding Value3}" />
        <customControls:KeyValueControl Key="Bool1" Value="{Binding Bool1}" Style="{StaticResource CheckBoxStyle}"/>
        <customControls:KeyValueControl Key="Bool2" Value="{Binding Bool2}" Style="{StaticResource CheckBoxStyle}"/>
    </ItemsControl>
    

    【讨论】:

    • 如果是控制库,放入Themes/Generic.xaml
    • 这不支持基本的可访问性。使用Label 标记事物,而不是TextBlock;并适当设置“目标”属性。
    【解决方案2】:

    这真的取决于您将来想用这些控件做什么。如果您想多次重用这种控件(并且可能即时创建它),最好创建 UserControl 并对其进行编程。然后,您可以以非常简单的方式轻松地重用它(例如放入 StackPanel)。

    LabelTextBox.xaml 的代码

    <UserControl x:Class="YourProject.LabelTextBox"
                 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" 
                 mc:Ignorable="d" 
                 d:DesignHeight="49" d:DesignWidth="314" MinHeight="49" MaxHeight="49">
        <Grid>
            <Label Content="Label" Height="28" HorizontalAlignment="Left" Name="BaseLabel" VerticalAlignment="Top" />
            <TextBox Height="23" Margin="0,26,0,0" Name="BaseTextBox" VerticalAlignment="Top" />
        </Grid>
    </UserControl>
    

    LabelTextBox.xaml.cs 的代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace YourProject
    {
        /// <summary>
        /// Interaction logic for LabelTextBox.xaml
        /// </summary>
        public partial class LabelTextBox : UserControl
        {
            public LabelTextBox()
            {
                InitializeComponent();
            }
    
    
    
            string LocalLabel = "";
            string LocalTextBox = "";
    
            public string Label
            {
                get { return LocalLabel; }
                set
                {
                    LocalLabel = value;
                    BaseLabel.Content = value;
                }
            }
    
            public string TextBox
            {
                get { return LocalTextBox; }
                set
                {
                    LocalTextBox = value;
                    BaseTextBox.Text = value;
                }
            }
        }
    }
    

    您可以使用新控件的 Label 和 TextBox 属性更改 Label 文本和 TextBox 内容(隐藏在设计器中 Properties 的“Other”部分。您还可以为 UserControl 编写附加功能。

    如果您不需要过多地重用这些控件,其他解决方案就足够了。

    【讨论】:

    【解决方案3】:

    我通常会这样做:

    <StackPanel>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Label Margin="5">Repository URL:</Label>
                    <TextBox Grid.Column="1" Margin="5"></TextBox>
                </Grid>
    </StackPanel>
    

    如果您经常这样做,您可以创建一个用户控件或数据模板。但是 WPF 只是一种冗长的标记语言……

    【讨论】:

      【解决方案4】:

      如果您希望灵活地操作此文本标签结构,我建议将每个 TextBox 和 Label 包装在停靠面板中,并将停靠设置为适用于所有标签和文本框的样式。

      所以它会像

      <StackPanel>
        <StackPanel.Resources>
           <Style TargetType={x:Type Label}>
            <Setter Property="DockPanel.Dock" Value="Top"/>
           </Style>
         </StackPanel.Resources>
      
         <DockPanel>
           <Label></Label>
           <TextBox></TextBox>
         </DockPanel>   
        <DockPanel>
          <Label></Label>
         <TextBox></TextBox>
        </DockPanel>
      
       </StackPanel>
      

      【讨论】:

        【解决方案5】:

        创建一个类 X,其中包含实现 INotifyPropertyChanged 的​​标签和文本。制作一个 ObservableCollection。这将是 ListBox、ComboBox、StackPanel 的 ItemsSource.. 无论您选择什么。创建一个以您希望的方式显示 X 的 DataTemplate。

        【讨论】:

          猜你喜欢
          • 2011-02-01
          • 1970-01-01
          • 2013-01-23
          • 2016-11-09
          • 2011-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-07
          相关资源
          最近更新 更多