【发布时间】:2016-08-29 14:24:42
【问题描述】:
我正在为 Windows 8.1 Universal/UWP 的 XAML 应用程序创建自定义控件,并不断发现细微差别。我似乎找不到任何关于创建现有控件(如 TextBox)的自定义实现的优秀教程,所以我一直在查看 Telerik 等控件的源代码,以尝试了解他们的自定义控件是如何工作的。
我遇到的最新问题是即使是最简单的自定义文本框也无法在光标停留在条目开头的情况下创建。当我继续输入文本时,光标停留在开头,即使文本被附加到末尾。我通过在它下面添加一个正常的文本框来验证它不是模拟器的问题,它可以正常工作。我确定这与我创建自定义控件的方式有关。
这是我的控制:
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>
我尝试将绑定更改为使用双向绑定:
{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, Path=Text}
我也尝试订阅 TextChanged 事件并根据新文本执行 Select 以尝试移动光标,但这些都不起作用:
private void CustomTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
Select(Text.Length, 0);
}
更新
在更改为从Control, 继承之后,我又回到了原来的问题。订阅 TextChanged 事件时,我无法让 Text 属性实时更新。我为此a created a new thread,因为它走的路径与此不同。
旁注:我什至尝试从 TextBox 继承的原因是因为 Telerik 的 RadTextBox 控件就是这样实现的。
【问题讨论】:
-
你犯了一个常见的错误。 ControlTemplate 应该不包含另一个文本框。您已将一个 TextBox 嵌套在另一个 TextBox 中。孩子们的事件和其他一切都没有连接到
CustomTextBox -
@lokusking - 谢谢,我已经改回从
Control继承,但现在已经绕了一圈。我已经用指向新线程的链接更新了我的评论,因为它与我上面描述的问题并不完全相关。
标签: c# xaml win-universal-app uwp uwp-xaml