简体   繁体   中英

How to group together Textblock and Textbox

I am making the UIs for entering master data for various business entities (customer, etc). I run into this need to group together a TextBlock and a TextBox together frequently. ie

<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" />

Is there any way to do this with less typing? ie

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

Or possibly, any libs which offer something like this?

EDIT : Forget the container Grid for a moment and assume it is a StackPanel.

Here's a step-by-step solution that I managed to put together. To set the stage, I'm going to assume we've got a very simple UserControl that has the following XAML content.

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

From an XAML that uses our UserControl we'd essentially want to set a data binding for the Text property on TBox . Idealy we could use a plain syntax like:

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

unfortunately I don't know any XAML syntax that would allow targeting an sub-element's property, so the next best thing would be to introduce a "staging" property in the UserControl itself and bind through that.

Since Binding only works for Dependency properties, the property we'll introduce needs to be a DependencyProperty . We'll also bind the Text property of TBox straight to our DependencyProperty from code.

The code-behind for the UserControl looks like this:

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); }
        }
    }
}

With this in place we can use the UserControl like this, binding to the TBValue property:

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

What you want to achieve (Master-Detail-Views) is actually well supported by Visual Studio out of the box. Open the following Menu structure : Project -> Add Data Source , then choose data source type Object . In the following, select the classes that you want to generate input fields for and finish the wizard.

在此处输入图片说明

Then, if not already open, open up your Data Sources tool window (Shift+Alt+D) . You should see a DataSource of the type you just generated. To get a labelled field for each property of the object, open the source dropdown and click Details .

在此处输入图片说明

Note that the properties have such dropdowns as well, so that you can choose how you want to edit them (ComboBox, TextBox, Custom, no editor,...). Now just drag the DataSource onto your window. You will get a Grid that's filled with all the labels and editors you desired. DataBinding and validation is also supported right away, so all you will have to do is set the generated Grid's DataContext .

Hope this saves you some work.

PS The screenshots are made in my german VS instance, still I thought they might help you identify the right dialogues / windows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM