Browse Source

Implement password char on TextBox rather than separate control.

pull/1544/head
Dan Walmsley 8 years ago
parent
commit
aca0fb3eba
  1. 3
      samples/ControlCatalog/Pages/TextBoxPage.xaml
  2. 47
      src/Avalonia.Controls/PasswordBox.cs
  3. 40
      src/Avalonia.Controls/TextBox.cs
  4. 64
      src/Avalonia.Themes.Default/PasswordBox.xaml
  5. 4
      src/Avalonia.Themes.Default/TextBox.xaml

3
samples/ControlCatalog/Pages/TextBoxPage.xaml

@ -15,9 +15,10 @@
UseFloatingWatermark="True"
Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit."/>
<PasswordBox Width="200"
<TextBox Width="200"
Watermark="Password Box"
UseFloatingWatermark="True"
PasswordChar="*"
Text="Password" />
<TextBox Width="200" Text="Left aligned text" TextAlignment="Left" />
<TextBox Width="200" Text="Center aligned text" TextAlignment="Center" />

47
src/Avalonia.Controls/PasswordBox.cs

@ -1,47 +0,0 @@
using Avalonia.Controls.Primitives;
using Avalonia.Styling;
using System;
namespace Avalonia.Controls
{
public class PasswordBox : TextBox, IStyleable
{
Type IStyleable.StyleKey => typeof(PasswordBox);
public PasswordBox()
{
this.GetObservable(TextProperty).Subscribe(text =>
{
if (text != null)
{
DisplayText = new string(PasswordChar, text.Length);
}
else
{
DisplayText = null;
}
});
}
public static readonly StyledProperty<char> PasswordCharProperty = AvaloniaProperty.Register<PasswordBox, char>(nameof(PasswordChar), '*');
public char PasswordChar
{
get => GetValue(PasswordCharProperty);
set => SetValue(PasswordCharProperty, value);
}
public static readonly StyledProperty<string> DisplayTextProperty = AvaloniaProperty.Register<PasswordBox, string>(nameof(DisplayText));
public string DisplayText
{
get => GetValue(DisplayTextProperty);
set => SetValue(DisplayTextProperty, value);
}
protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
{
base.OnTemplateApplied(e);
}
}
}

40
src/Avalonia.Controls/TextBox.cs

@ -30,7 +30,10 @@ namespace Avalonia.Controls
nameof(CaretIndex),
o => o.CaretIndex,
(o, v) => o.CaretIndex = v);
public static readonly StyledProperty<char> PasswordCharProperty =
AvaloniaProperty.Register<TextBox, char>(nameof(PasswordChar));
public static readonly StyledProperty<bool> IsReadOnlyProperty =
AvaloniaProperty.Register<TextBox, bool>(nameof(IsReadOnly));
@ -53,6 +56,9 @@ namespace Avalonia.Controls
defaultBindingMode: BindingMode.TwoWay,
enableDataValidation: true);
public static readonly StyledProperty<string> DisplayTextProperty =
AvaloniaProperty.Register<TextBox, string>(nameof(DisplayText));
public static readonly StyledProperty<TextAlignment> TextAlignmentProperty =
TextBlock.TextAlignmentProperty.AddOwner<TextBox>();
@ -78,7 +84,7 @@ namespace Avalonia.Controls
public bool Equals(UndoRedoState other) => ReferenceEquals(Text, other.Text) || Equals(Text, other.Text);
}
private string _text;
private int _caretIndex;
private int _selectionStart;
@ -117,6 +123,18 @@ namespace Avalonia.Controls
horizontalScrollBarVisibility,
BindingPriority.Style);
_undoRedoHelper = new UndoRedoHelper<UndoRedoState>(this);
this.GetObservable(TextProperty).Subscribe(text =>
{
if (PasswordChar != default(char))
{
DisplayText = new string(PasswordChar, text.Length);
}
else
{
DisplayText = Text;
}
});
}
public bool AcceptsReturn
@ -147,7 +165,13 @@ namespace Avalonia.Controls
_undoRedoHelper.UpdateLastState();
}
}
public char PasswordChar
{
get => GetValue(PasswordCharProperty);
set => SetValue(PasswordCharProperty, value);
}
public bool IsReadOnly
{
get { return GetValue(IsReadOnlyProperty); }
@ -208,6 +232,12 @@ namespace Avalonia.Controls
}
}
public string DisplayText
{
get => GetValue(DisplayTextProperty);
set => SetValue(DisplayTextProperty, value);
}
public TextAlignment TextAlignment
{
get { return GetValue(TextAlignmentProperty); }
@ -832,9 +862,9 @@ namespace Avalonia.Controls
private void SetTextInternal(string value)
{
try
{
{
_ignoreTextChanges = true;
SetAndRaise(TextProperty, ref _text, value);
SetAndRaise(TextProperty, ref _text, value);
}
finally
{

64
src/Avalonia.Themes.Default/PasswordBox.xaml

@ -1,64 +0,0 @@
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="PasswordBox">
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/>
<Setter Property="BorderThickness" Value="{DynamicResource ThemeBorderThickness}"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="Template">
<ControlTemplate>
<Border Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel Margin="{TemplateBinding Padding}">
<TextBlock Name="floatingWatermark"
Foreground="{DynamicResource ThemeAccentBrush}"
FontSize="{DynamicResource FontSizeSmall}"
Text="{TemplateBinding Watermark}"
DockPanel.Dock="Top">
<TextBlock.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="UseFloatingWatermark"/>
<Binding RelativeSource="{RelativeSource TemplatedParent}"
Path="DisplayText"
Converter="{x:Static StringConverters.NotNullOrEmpty}"/>
</MultiBinding>
</TextBlock.IsVisible>
</TextBlock>
<DataValidationErrors>
<ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
<Panel>
<TextBlock Name="watermark"
Opacity="0.5"
Text="{TemplateBinding Watermark}"
IsVisible="{TemplateBinding Path=Text, Converter={x:Static StringConverters.NullOrEmpty}}"/>
<TextPresenter Name="PART_TextPresenter"
Text="{TemplateBinding Text, Mode=TwoWay}"
CaretIndex="{TemplateBinding CaretIndex}"
SelectionStart="{TemplateBinding SelectionStart}"
SelectionEnd="{TemplateBinding SelectionEnd}"
TextAlignment="{TemplateBinding TextAlignment}"
TextWrapping="{TemplateBinding TextWrapping}"/>
</Panel>
</ScrollViewer>
</DataValidationErrors>
</DockPanel>
</Border>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="TextBox:pointerover /template/ Border#border">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderDarkBrush}"/>
</Style>
<Style Selector="TextBox:focus /template/ Border#border">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderDarkBrush}"/>
</Style>
<Style Selector="TextBox:error /template/ Border#border">
<Setter Property="BorderBrush" Value="{DynamicResource ErrorBrush}"/>
</Style>
</Styles>

4
src/Avalonia.Themes.Default/TextBox.xaml

@ -38,12 +38,12 @@
Text="{TemplateBinding Watermark}"
IsVisible="{TemplateBinding Path=Text, Converter={x:Static StringConverters.NullOrEmpty}}"/>
<TextPresenter Name="PART_TextPresenter"
Text="{TemplateBinding Text, Mode=TwoWay}"
Text="{TemplateBinding DisplayText, Mode=TwoWay}"
CaretIndex="{TemplateBinding CaretIndex}"
SelectionStart="{TemplateBinding SelectionStart}"
SelectionEnd="{TemplateBinding SelectionEnd}"
TextAlignment="{TemplateBinding TextAlignment}"
TextWrapping="{TemplateBinding TextWrapping}"/>
TextWrapping="{TemplateBinding TextWrapping}"/>
</Panel>
</ScrollViewer>
</DataValidationErrors>

Loading…
Cancel
Save