Windows 通用应用中的标签文本框

Labeled TextBox in Windows Universal App

我正在尝试使用 C#XAML 在 windows 通用应用程序中实现带标签的 TextBox ,但我没有得到return中TextBox的值,只是空字符串。

我的 generic.xaml 的代码如下所示:

<Style TargetType="template:LabeledTextBox">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="template:LabeledTextBox">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="{TemplateBinding Label}" FontWeight="Bold" VerticalAlignment="Center" Margin="10,0" />
                    <TextBox Text="{TemplateBinding Value}" IsReadOnly="{TemplateBinding IsReadOnly}" VerticalAlignment="Center" Margin="20,0,10,0" Grid.Row="1" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

控件如下所示:

public sealed class LabeledTextBox : Control, IParameterReturnable
{
    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabeledTextBox), new PropertyMetadata(default(string)));
    public string Label
    {
        get { return this.GetValue(LabelProperty).ToString(); }
        set { this.SetValue(LabelProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(LabeledTextBox), new PropertyMetadata(default(string)));
    public string Value
    {
        get { return this.GetValue(ValueProperty).ToString(); }
        set { this.SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(LabeledTextBox), new PropertyMetadata(false));
    public string IsReadOnly
    {
        get { return this.GetValue(IsReadOnlyProperty).ToString(); }
        set { this.SetValue(IsReadOnlyProperty, value); }
    }

    public LabeledTextBox()
    {
        this.DefaultStyleKey = typeof(LabeledTextBox);
    }

    public LabeledTextBox(Parameter parameter)
    {
        this.Label = parameter.DisplayName;
        this.Value = parameter.DefaultValue ?? "";
        this.DefaultStyleKey = typeof(LabeledTextBox);
    }

    public string GetKey()
    {
        return this.Label;
    }

    public string GetValue()
    {
        return this.Value;
    }
}

您可以随意忽略我的 IParameterReturnable,我正在使用它来访问 GetKey()GetValue(),同时循环遍历这些标记为-的不同类型控件。

那么我错过了什么,我做错了什么?

非常感谢您提供的所有有用且善意的回答!

编辑:添加控件的代码

控件是用 C# 动态添加的,如下所示:

foreach (Parameter parameter in parameters)
{
    stackPanel.Children.Add(new LabeledTextBox(parameter));
}

但在 Xaml 中看起来像这样:

<templates:LabeledTextBox Label="[Label]" Value="[Value]" IsReadOnly="False" />

会这样读出来:

foreach(IParameterReturnable parameter in stackPanel.Children)
{
    string val = parameter.GetValue() // <= this will always return the default value
}

您没有使用模板 TextBox 中的新值更新 Value 属性。

在您的 generic.xaml 中为您的 TextBox 添加一个名称:<TextBox x:Name="PART_TextBox"...

那么你的 LabeledTextBox class 应该是这样的:

[TemplatePart(Name = "PART_TextBox", Type = typeof(TextBox))]
public sealed class LabeledTextBox : Control, IParameterReturnable
{
    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabeledTextBox), new PropertyMetadata(default(string)));
    public string Label
    {
        get { return this.GetValue(LabelProperty).ToString(); }
        set { this.SetValue(LabelProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(LabeledTextBox), new PropertyMetadata(default(string)));
    public string Value
    {
        get { return this.GetValue(ValueProperty).ToString(); }
        set { this.SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(LabeledTextBox), new PropertyMetadata(false));
    public string IsReadOnly
    {
        get { return this.GetValue(IsReadOnlyProperty).ToString(); }
        set { this.SetValue(IsReadOnlyProperty, value); }
    }

    public LabeledTextBox()
    {
        this.DefaultStyleKey = typeof(LabeledTextBox);
    }

    private TextBox _textBox;

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        _textBox = GetTemplateChild("PART_TextBox") as TextBox;

        if (_textBox != null)
        {
            _textBox.TextChanged += TextBoxOnTextChanged;
        }
    }

    private void TextBoxOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
    {
        this.Value = _textBox.Text;
    }

    public LabeledTextBox(Parameter parameter)
    {
        this.Label = parameter.DisplayName;
        this.Value = parameter.DefaultValue ?? "";
        this.DefaultStyleKey = typeof(LabeledTextBox);
    }

    public string GetKey()
    {
        return this.Label;
    }

    public string GetValue()
    {
        return this.Value;
    }
}

请注意,我添加了 TemplatePart 属性并覆盖了 OnApplyTemplate,我在其中注册了 TextBoxTextChanged 事件。当文本更改时,我更新 Value 依赖项 属性.