在WPF中展示文本标签(例如“名称”)与文本框的最佳实践是什么?
我想要在文本框上方添加一个标签“名称”,并希望有许多类似的标签/文本框。
我应该将标签/文本框对放入垂直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>
这真的取决于您未来想要如何使用这些控件。如果您想多次重复使用此类控件(甚至是动态创建它),最好创建一个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;
}
}
}
}
Target
。更多信息请参见:https://www.wpf-tutorial.com/basic-controls/the-label-control/ - BrainSlugs83<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>
我通常会这样做:
<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>
如果您经常这样做,可以创建一个UserControl或Datatemplate。但是WPF只是一种冗长的标记语言...
<Style TargetType="{x:Type TextBox}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="ControlLabel" Grid.Column="0"
VerticalAlignment="Top" HorizontalAlignment="Left"
Text="{TemplateBinding Tag}" />
<Line x:Name="LineColumnLabel" Grid.Column="1" X1="0" X2="0" Y1="0" Y2="{TemplateBinding Height}"
Stroke="#B31C1C1C" StrokeThickness="0.5" Margin="5,0,5,0" />
<ScrollViewer Grid.Column="2" x:Name="PART_ContentHost"
IsTabStop="{TemplateBinding ScrollViewer.IsTabStop}"
TextElement.Foreground="{TemplateBinding Foreground}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Tag" Value="{x:Null}">
<Setter TargetName="ControlLabel" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ControlLabel" Property="Margin" Value="0" />
<Setter TargetName="LineColumnLabel" Property="Visibility" Value="Collapsed" />
<Setter TargetName="LineColumnLabel" Property="Margin" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
而且
<Grid>
<TextBox Tag="The Name"/>
</Grid>
Themes/Generic.xaml
。 - Johan Larsson