我正在为Windows 8.1 Universal / UWP的XAML应用程序创建自定义控件,并且不断发现细微差别。我似乎无法找到有关创建现有控件的自定义实现(如TextBox)的任何精彩教程,因此我一直在查看Telerik等控件的源代码,以尝试了解其自定义控件的工作原理
我遇到的最新问题是,如果没有光标停留在条目的开头,即使是最简单的自定义TextBox也无法创建。当我一直输入文本时,光标停留在开头,即使文本被附加到结尾。我通过在其下方添加一个正常运行的常规文本框来验证模拟器不是问题。我确定这与我创建自定义控件的方式有关。
这是我的控制权:
public class CustomTextBox : TextBox
{
public CustomTextBox()
{
DefaultStyleKey = typeof(CustomTextBox);
}
}
这是我的Generic.xaml文件,其中包含用于说明问题的模板:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:customControls="using:CustomControls">
<Style TargetType="customControls:CustomTextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="customControls:CustomTextBox">
<TextBox Text="{TemplateBinding Text}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
最后,这是我的页面XAML在您运行它并在第一个文本框中输入文本时显示问题。 TextBlock用于显示我输入文本的实时更改,这对我原来的问题至关重要:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="{Binding ElementName=txtTextBox, Path=Text}" Grid.Row="0" VerticalAlignment="Bottom" />
<local:CustomTextBox Grid.Row="1" x:Name="txtTextBox" />
<TextBox Grid.Row="2"></TextBox>
</Grid>
我尝试更改绑定以使用TwoWay绑定:
{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, Path=Text}
我还尝试订阅TextChanged事件并在新文本的作用下执行选择以尝试移动光标,但这些都没有奏效:
private void CustomTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
Select(Text.Length, 0);
}
更新
更改为继承自Control,
之后,我已完整回到原始问题。在订阅TextChanged事件时,我无法实时更新Text属性。我a created a new thread因为它走的路径不同于此。
附注:我甚至试图从TextBox
继承的原因是因为Telerik的RadTextBox控件是如何实现的。
答案 0 :(得分:2)
正如@lokusking所提到的那样,将TextBox
嵌套在另一个TextBox
中并不正确,因为CustomTextBox
继承自TextBox
,你将会需要自定义ControlTemplate
,如TextBox styles and templates。
您可以复制TextBox
的默认模板并替换为您的CustomTextBox
并尝试一下,它将解决您的问题。此外,您还可以创建自己的模板,例如:Create Your First WinRT WatermarkTextBox Control。但是不要在TextBox
中嵌套另一个CustomTextBox
,你可以在这个帖子中引用答案:Why use a templated control over a UserControl?,它很好地解释了我们使用模板控制的地点和原因。
如果要注册其他属性,可以使用DependencyProperty,如果要注册新事件,可以参考Custom events and event accessors in Windows Runtime Components。