【发布时间】:2011-05-22 08:41:58
【问题描述】:
在 WPF 中使用 TextBox 显示文本标签(例如“名称”)的最佳做法是什么? 我想要文本框上方的标签“名称”和许多类似的标签/文本框。 我应该将 Label/TextBox 对放入垂直 StackPanel 中吗?
有没有更简单的解决方案?
【问题讨论】:
在 WPF 中使用 TextBox 显示文本标签(例如“名称”)的最佳做法是什么? 我想要文本框上方的标签“名称”和许多类似的标签/文本框。 我应该将 Label/TextBox 对放入垂直 StackPanel 中吗?
有没有更简单的解决方案?
【问题讨论】:
这是一个可以做到这一点的控件:
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;并适当设置“目标”属性。
这真的取决于您将来想用这些控件做什么。如果您想多次重用这种控件(并且可能即时创建它),最好创建 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 编写附加功能。
如果您不需要过多地重用这些控件,其他解决方案就足够了。
【讨论】:
Target。更多信息:wpf-tutorial.com/basic-controls/the-label-control
我通常会这样做:
<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 只是一种冗长的标记语言……
【讨论】:
如果您希望灵活地操作此文本标签结构,我建议将每个 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>
【讨论】:
创建一个类 X,其中包含实现 INotifyPropertyChanged 的标签和文本。制作一个 ObservableCollection。这将是 ListBox、ComboBox、StackPanel 的 ItemsSource.. 无论您选择什么。创建一个以您希望的方式显示 X 的 DataTemplate。
【讨论】: