使用WPF中的TextBox显示文本标签(例如“Name”)的最佳做法是什么? 我想在TextBox上面有一个标签“Name”和许多类似的Labels / TextBoxes。 我应该将Label / TextBox对放入垂直StackPanel吗?
是否有更简单的解决方案?
答案 0 :(得分:9)
这实际上取决于您将来要对这些控件做些什么。如果你想多次重复使用这种控件(并且可能在运行中创建它),那么最好创建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内容(隐藏在设计器中属性的“其他”部分。您还可以为UserControl编写其他函数。
如果您不需要重复使用这些控件,其他解决方案就足够了。
答案 1 :(得分:7)
这是一个控件:
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>
答案 2 :(得分:3)
如果您希望灵活地操作此文本标签结构,我建议将每个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>
答案 3 :(得分:1)
我通常做这样的事情:
<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只是一种冗长的标记语言......
答案 4 :(得分:0)
创建一个包含实现INotifyPropertyChanged的标签和文本的类X.制作一个ObservableCollection。这将是ListBox,ComboBox,StackPanel的ItemsSource ......无论你选择什么。创建一个以您希望的方式显示X的DataTemplate。