如何将Textblock和Textbox组合在一起

时间:2013-03-08 06:40:59

标签: c# wpf .net-4.0

我正在制作用于输入各种业务实体(客户等)的主数据的UI。我遇到这种需要经常将TextBlock和TextBox组合在一起。即。

<Label Content="Civil Status:" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" />
<TextBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="3" Name="civilStatusTextBox" Text="{Binding Path=CivilStatus, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
<Label Content="Company:" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" />
<TextBox Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="3" Name="companyTextBox" Text="{Binding Path=Company, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />

有没有办法用更少的打字来做到这一点?即。

<custom:LabeledTextBox Label="Civil Status:" Text="{Binding Path=CivilStatus, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" ... />

或者可能是任何提供类似内容的库?

编辑:暂时忘记容器Grid并假设它是一个StackPanel。

2 个答案:

答案 0 :(得分:2)

这是我设法整理的逐步解决方案。为了设置阶段,我将假设我们有一个非常简单的UserControl,它具有以下XAML内容。

<UserControl x:Class="WpfApplication2.UserControl1" [ ... auto gen code removed ... ] >
     <TextBox MinWidth="50" x:Name="TBox" />        
</UserControl>

从使用我们的UserControl的XAML开始,我们基本上想要为Text上的TBox属性设置数据绑定。理想情况下,我们可以使用简单的语法,如:

<local:UserControl1 TBox.Text="{Binding ...}" />

不幸的是,我不知道任何允许定位子元素属性的XAML语法,所以接下来最好的方法是在UserControl本身引入一个“staging”属性并通过它绑定。

由于Binding仅适用于依赖属性,因此我们引入的属性需要为DependencyProperty。我们还将Text TBox属性直接绑定到代码中的DependencyProperty。

UserControl的代码隐藏如下:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();

            // Set binding from code
            this.TBox.DataContext = this;
            this.TBox.SetBinding(TextBox.TextProperty, new Binding { Path = new PropertyPath("TBValue"), Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });
        }

        public static readonly DependencyProperty TBValueProperty = DependencyProperty.Register("TBValue", typeof(string), typeof(UserControl1));

        public string TBValue
        {
            get { return this.GetValue(TBValueProperty) as string; }
            set { this.SetValue(TBValueProperty, value); }
        }
    }
}

有了这个,我们可以像这样使用UserControl,绑定到TBValue属性:

<local:UserControl1 TBValue="{Binding Path=Test, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

答案 1 :(得分:0)

您想要实现的目标(Master-Detail-Views)实际上得到了Visual Studio的开箱即用支持。打开以下菜单结构:Project -> Add Data Source,然后选择数据源类型Object。在下面,选择要为其生成输入字段的类,然后完成向导。

enter image description here

然后,如果尚未打开,请打开数据源工具窗口(Shift+Alt+D)。您应该看到刚刚生成的类型的DataSource。要为对象的每个属性获取带标签的字段,请打开源下拉列表,然后单击Details

enter image description here

请注意,属性也有这样的下拉菜单,因此您可以选择编辑它们的方式(ComboBox,TextBox,Custom,no editor,...)。 现在只需将DataSource拖到窗口上即可。您将获得一个网格,其中包含您想要的所有标签和编辑器。立即支持DataBinding和验证,因此您只需设置生成的Grid DataContext

希望这能为您节省一些工作。

P.S。截图是在我的德国VS实例中制作的,我仍然认为它们可以帮助您识别正确的对话框/窗口。