I'm trying to realize a labeled TextBox
in a windows universal app using C# and XAML , but I did not get the value of the TextBox
in return, just empty string.
The code of my generic.xaml for it looks like this:
<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>
The control looks like this:
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;
}
}
You are free to ignore my IParameterReturnable , which I am using to access to GetKey()
and GetValue()
while looping through different types of these labeled-controls.
So what am I missing, what am I doing wrong?
Thank you very much for all helpful and well meant answers!
EDIT: Code for adding Control
The control is added dynamically with C# like this:
foreach (Parameter parameter in parameters)
{
stackPanel.Children.Add(new LabeledTextBox(parameter));
}
But it would looks like this in Xaml:
<templates:LabeledTextBox Label="[Label]" Value="[Value]" IsReadOnly="False" />
It will be read out like this:
foreach(IParameterReturnable parameter in stackPanel.Children)
{
string val = parameter.GetValue() // <= this will always return the default value
}
You are not updating the Value
property with a new value from your templated TextBox
.
In your generic.xaml
add a name to your TextBox
: <TextBox x:Name="PART_TextBox"...
Then your LabeledTextBox
class should look like this:
[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;
}
}
Notice that I have added the TemplatePart
attribute and overriden the OnApplyTemplate
in which I register for the TextChanged
event of the TextBox
. When the text changes, I update the Value
dependency property.
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.