6 changed files with 169 additions and 19 deletions
@ -0,0 +1,112 @@ |
|||
using Avalonia; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Primitives; |
|||
using Avalonia.Data; |
|||
using Avalonia.Input; |
|||
using Avalonia.LogicalTree; |
|||
using Avalonia.Metadata; |
|||
using Avalonia.Threading; |
|||
using Avalonia.VisualTree; |
|||
using System; |
|||
|
|||
namespace ControlCatalog |
|||
{ |
|||
public class EditableTextBlock : TemplatedControl |
|||
{ |
|||
private string _text; |
|||
private TextBox _textBox; |
|||
|
|||
public static readonly DirectProperty<EditableTextBlock, string> TextProperty = TextBlock.TextProperty.AddOwner<EditableTextBlock>( |
|||
o => o.Text, |
|||
(o, v) => o.Text = v, |
|||
defaultBindingMode: BindingMode.TwoWay, |
|||
enableDataValidation: true); |
|||
|
|||
[Content] |
|||
public string Text |
|||
{ |
|||
get { return _text; } |
|||
set |
|||
{ |
|||
SetAndRaise(TextProperty, ref _text, value); |
|||
} |
|||
} |
|||
|
|||
public static readonly StyledProperty<bool> InEditModeProperty = |
|||
AvaloniaProperty.Register<EditableTextBlock, bool>(nameof(InEditMode)); |
|||
|
|||
public bool InEditMode |
|||
{ |
|||
get { return GetValue(InEditModeProperty); } |
|||
set { SetValue(InEditModeProperty, value); } |
|||
} |
|||
|
|||
protected override void OnTemplateApplied(TemplateAppliedEventArgs e) |
|||
{ |
|||
base.OnTemplateApplied(e); |
|||
|
|||
_textBox = e.NameScope.Find<TextBox>("PART_TextBox"); |
|||
|
|||
_textBox.KeyUp += _textBox_KeyUp; |
|||
} |
|||
|
|||
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e) |
|||
{ |
|||
base.OnDetachedFromLogicalTree(e); |
|||
|
|||
_textBox.KeyUp -= _textBox_KeyUp; |
|||
} |
|||
|
|||
private void _textBox_KeyUp(object sender, KeyEventArgs e) |
|||
{ |
|||
if (e.Key == Key.Enter || e.Key == Key.Escape) |
|||
{ |
|||
ExitEditMode(); |
|||
} |
|||
} |
|||
|
|||
private void EnterEditMode() |
|||
{ |
|||
InEditMode = true; |
|||
(VisualRoot as IInputRoot).MouseDevice.Capture(_textBox); |
|||
_textBox.CaretIndex = Text.Length - 1; |
|||
|
|||
Dispatcher.UIThread.InvokeAsync(() => |
|||
{ |
|||
_textBox.Focus(); |
|||
}); |
|||
} |
|||
|
|||
private void ExitEditMode() |
|||
{ |
|||
InEditMode = false; |
|||
(VisualRoot as IInputRoot).MouseDevice.Capture(null); |
|||
} |
|||
|
|||
protected override void OnPointerPressed(PointerPressedEventArgs e) |
|||
{ |
|||
base.OnPointerPressed(e); |
|||
|
|||
if (!InEditMode) |
|||
{ |
|||
if (e.MouseButton == MouseButton.Middle) |
|||
{ |
|||
EnterEditMode(); |
|||
} |
|||
else if (e.ClickCount == 2) |
|||
{ |
|||
EnterEditMode(); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
var hit = this.InputHitTest(e.GetPosition(this)); |
|||
|
|||
if (!this.IsVisualAncestorOf(hit)) |
|||
{ |
|||
ExitEditMode(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
<Styles xmlns="https://github.com/avaloniaui" |
|||
xmlns:cont="clr-namespace:ControlCatalog;assembly=ControlCatalog"> |
|||
<Style Selector="cont|EditableTextBlock"> |
|||
<Setter Property="BorderThickness" Value="0"/> |
|||
<Setter Property="Padding" Value="0"/> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Grid> |
|||
<TextBlock Text="{TemplateBinding Text}" IsVisible="{TemplateBinding !InEditMode}" /> |
|||
<TextBox Text="{TemplateBinding Text}" IsVisible="{TemplateBinding InEditMode}" Name="PART_TextBox" Foreground="Black" /> |
|||
</Grid> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
</Styles> |
|||
@ -1,30 +1,34 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui"> |
|||
<StackPanel Orientation="Vertical" Gap="4"> |
|||
<TextBlock Classes="h1">TextBox</TextBlock> |
|||
<TextBlock Classes="h2">A control into which the user can input text</TextBlock> |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:local="clr-namespace:ControlCatalog"> |
|||
<StackPanel Orientation="Vertical" Gap="4"> |
|||
<TextBlock Classes="h1">TextBox</TextBlock> |
|||
<TextBlock Classes="h2">A control into which the user can input text</TextBlock> |
|||
|
|||
<local:EditableTextBlock Text="{Binding TestText}" /> |
|||
<TextBlock Classes="h2" Text="{Binding TestText}" /> |
|||
|
|||
<StackPanel Orientation="Horizontal" |
|||
<StackPanel Orientation="Horizontal" |
|||
Margin="0,16,0,0" |
|||
HorizontalAlignment="Center" |
|||
Gap="16"> |
|||
<StackPanel Orientation="Vertical" Gap="8"> |
|||
<TextBox Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit." Width="200" /> |
|||
<TextBox Width="200" Watermark="Watermark" /> |
|||
<TextBox Width="200" |
|||
<StackPanel Orientation="Vertical" Gap="8"> |
|||
<TextBox Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit." Width="200" /> |
|||
<TextBox Width="200" Watermark="Watermark" /> |
|||
<TextBox Width="200" |
|||
Watermark="Floating Watermark" |
|||
UseFloatingWatermark="True" |
|||
Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit."/> |
|||
<TextBox Width="200" Text="Left aligned text" TextAlignment="Left" /> |
|||
<TextBox Width="200" Text="Center aligned text" TextAlignment="Center" /> |
|||
<TextBox Width="200" Text="Right aligned text" TextAlignment="Right" /> |
|||
</StackPanel> |
|||
<TextBox Width="200" Text="Left aligned text" TextAlignment="Left" /> |
|||
<TextBox Width="200" Text="Center aligned text" TextAlignment="Center" /> |
|||
<TextBox Width="200" Text="Right aligned text" TextAlignment="Right" /> |
|||
</StackPanel> |
|||
|
|||
<StackPanel Orientation="Vertical" Gap="8"> |
|||
<TextBox AcceptsReturn="True" TextWrapping="Wrap" Width="200" Height="125" |
|||
<StackPanel Orientation="Vertical" Gap="8"> |
|||
<TextBox AcceptsReturn="True" TextWrapping="Wrap" Width="200" Height="125" |
|||
Text="Multiline TextBox with TextWrapping.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est." /> |
|||
<TextBox AcceptsReturn="True" Width="200" Height="125" |
|||
<TextBox AcceptsReturn="True" Width="200" Height="125" |
|||
Text="Multiline TextBox with no TextWrapping.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est." /> |
|||
</StackPanel> |
|||
</StackPanel> |
|||
</StackPanel> |
|||
</StackPanel> |
|||
</StackPanel> |
|||
</UserControl> |
|||
Loading…
Reference in new issue