问题描述
因此,我试图使用Avalonia UI框架创建一个自定义TextBox
控件,以支持securestring
(基本上我想覆盖OnTextinput()
)。
namespace myProject.UI.Controls
{
public class ProtectedTextBox : TextBox
{
}
}
据我了解,继承ProtectedTextBox
的行为应与继承自TextBox
的行为完全一样。
但是,当使用我的ProtectedTextBox
时,它似乎根本没有被渲染。我敢肯定,我在这里只是犯了一些愚蠢的错误,但是对于我的一生,我不知道为什么它不起作用。
预期的行为:
这是我用于测试的axaml代码:
<Frame xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:lControls="clr-namespace:myProject.UI.Controls;assembly=myProject"
mc:Ignorable="d" d:DesignWidth="1440" d:DesignHeight="900"
x:Class="myProject.UI.Frames.TestFrame">
<DockPanel Width="1440" Height="900">
<Panel DockPanel.Dock="Top" Background="Aqua">
<TextBox Width="200" Height="100" Background="Red"/>
</Panel>
<Panel/>
</DockPanel>
</Frame>
它产生了以下非常好的输出:(我们有一个丑陋但工作正常的TextBox
)
实际行为:
使用ProtectedTextBox
(直接来自TextBox
)时不会有任何差异
<Frame xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:lControls="clr-namespace:myProject.UI.Controls;assembly=myProject"
mc:Ignorable="d" d:DesignWidth="1440" d:DesignHeight="900"
x:Class="myProject.UI.Frames.TestFrame">
<DockPanel Width="1440" Height="900">
<Panel DockPanel.Dock="Top" Background="Aqua">
<lControls:ProtectedTextBox Width="200" Height="100" Background="Red"/>
</Panel>
<Panel/>
</DockPanel>
</Frame>
但是,它只是不可见并且不会被渲染。 (Avalonia DevTools似乎知道它的存在,并且在LogicalTree中选择它时,应该突出显示ProtectedTextBox
的位置)。
所以出现了一些问题:
- 为什么子类的行为与父类有所不同。当然应该表现得一样吗?
- 这是否只是一些关于Avalonia的怪异现象(例如,Avalonia的渲染使用反射和
GetType()
会为这些不同的类返回不同的东西)? - 如何创建自定义
TextBox
控件?可能吗(无需自己痛苦地重新创建所有功能)?
解决方法
只需使用 StyleKey 并像这样实现 IStyleable:
public class MyTextBox : TextBox,IStyleable
{
Type IStyleable.StyleKey => typeof(TextBox);
...