So I am trying to create a custom TextBox
control with support for SecureString
(basically I want to override OnTextInput()
) using the Avalonia UI framework.
The obvious approach for me is to directly inherit from TextBox
. Like this
namespace myProject.UI.Controls
{
public class ProtectedTextBox : TextBox
{
}
}
To my understanding of inheritance the ProtectedTextBox
should now act exactly like the TextBox
it derives from.
However when using my ProtectedTextBox
it doesn't seem to get rendered at all. I'm certain that I'm just doing some silly mistake here, but for the life of me I can't figure out why it wouldn't work.
Expected behaviour:
This is the axaml code I use for testing:
<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>
It produced the following perfectly fine output: (We have an ugly but correctly working TextBox
)
Actual behaviour:
I wouldn't expect any differences when I use my ProtectedTextBox
(directly deriving from 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>
However it's just invisible and doesn't get rendered. (The Avalonia DevTools seem to know that it exists though and when selecting it in the LogicalTree the spot where my ProtectedTextBox
should be get's highlighted).
So a few questions arise:
- Why does my child class behave different than it's parent. Surely it should behave the same?
- Is this just some Avalonia specific weirdness (i.e. maybe Avalonia's rendering uses reflection and
GetType()
which would return different things for these different classes)? - How would I create a custom
TextBox
control? Is it possible at all (without painfully recreating all of it's functionality myself)?
Just use StyleKey and implement IStyleable like this:
See https://stackoverflow.com/a/51761372