Added a placeholder text in the text box, and made a few other UI tweaks.

This commit is contained in:
GoldenCrystal
2014-11-17 20:08:29 +01:00
parent 11f2619411
commit ea1a498aff
4 changed files with 241 additions and 8 deletions
+8 -8
View File
@@ -13,7 +13,7 @@
<Window.DataContext>
<local:CharacterInspectorViewModel />
</Window.DataContext>
<Grid Margin="10">
<Grid Margin="10">
<Grid.Resources>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource ResourceKey={x:Type Label}}">
<Setter Property="Margin" Value="3" />
@@ -37,7 +37,7 @@
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.ColumnSpan="2" ScrollViewer.VerticalScrollBarVisibility="Auto" MinLines="1" MaxLines="5" AcceptsReturn="True" Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.ColumnSpan="2" ScrollViewer.VerticalScrollBarVisibility="Auto" MinLines="1" MaxLines="5" AcceptsTab="True" AcceptsReturn="True" local:Placeholder.Text="Text to analyse" Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" />
<ListBox Grid.Row="1" Grid.RowSpan="3" ItemsSource="{Binding Characters}" SelectedIndex="{Binding SelectedCharacterIndex}">
<ListBox.ItemTemplate>
<DataTemplate>
@@ -45,7 +45,7 @@
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Grid.Row="1" Grid.Column="1" TextOptions.TextFormattingMode="Ideal" TextOptions.TextRenderingMode="Grayscale" Text="{Binding SelectedCharacterInfo.DisplayText}" FontSize="96" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Grid.Row="1" Grid.Column="1" TextOptions.TextHintingMode="Fixed" TextOptions.TextFormattingMode="Ideal" TextOptions.TextRenderingMode="Grayscale" Text="{Binding SelectedCharacterInfo.DisplayText}" FontSize="96" HorizontalAlignment="Center" VerticalAlignment="Center" />
<ScrollViewer Grid.Row="2" Grid.Column="1" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.Resources>
@@ -126,11 +126,11 @@
<TextBlock Grid.Row="19" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.UnihanNumericType, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.UnihanNumericType}" />
<TextBlock Grid.Row="20" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.NumericValue, Converter={StaticResource NullToVisibilityConverter}}" Text="Numeric Value" />
<TextBlock Grid.Row="20" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.NumericValue, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.NumericValue}" />
<TextBlock Grid.Row="21" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.ContributoryProperties, Converter={StaticResource NullToVisibilityConverter}}" Text="Contributory Properties" />
<TextBlock Grid.Row="21" Grid.Column="1" VerticalAlignment="Top" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.ContributoryProperties, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.ContributoryProperties}" />
<TextBlock Grid.Row="22" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.CoreProperties, Converter={StaticResource NullToVisibilityConverter}}" Text="Core Properties" />
<TextBlock Grid.Row="22" Grid.Column="1" VerticalAlignment="Top" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.CoreProperties, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.CoreProperties}" />
<TextBlock Grid.Row="21" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.ContributoryProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Contributory Properties" />
<TextBlock Grid.Row="21" Grid.Column="1" VerticalAlignment="Top" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.ContributoryProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.ContributoryProperties}" />
<TextBlock Grid.Row="22" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.CoreProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Core Properties" />
<TextBlock Grid.Row="22" Grid.Column="1" VerticalAlignment="Top" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.CoreProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.CoreProperties}" />
</Grid>
</ScrollViewer>
</Grid>
</Grid>
</Window>
+170
View File
@@ -0,0 +1,170 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Media;
namespace UnicodeCharacterInspector
{
// Inspired by http://stackoverflow.com/questions/833943/watermark-hint-text-placeholder-textbox-in-wpf
internal static partial class Placeholder
{
public static string GetText(DependencyObject obj)
{
return (string)obj.GetValue(TextProperty);
}
public static void SetText(DependencyObject obj, string value)
{
obj.SetValue(TextProperty, value);
}
public static readonly DependencyProperty TextProperty = DependencyProperty.RegisterAttached("Text", typeof(string), typeof(Placeholder), new PropertyMetadata(OnTextChanged));
private static readonly HashSet<Control> handledControls = new HashSet<Control>();
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as TextBoxBase;
if (d == null) return;
if (e.NewValue == null || "".Equals(e.NewValue)) UnregisterControl(control);
else UpdateControl(control, (string)e.NewValue);
}
private static void OnControlLoaded(object sender, RoutedEventArgs e)
{
var control = (Control)sender;
UpdateControl(control, GetText(control));
}
private static void OnTextBoxGotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
var control = (Control)sender;
RemoveAdorner(control);
}
private static void UpdateControl(Control control, string placeholderText)
{
if (handledControls.Add(control))
{
RegisterControl(control);
}
if (IsEmpty(control))
{
var adorner = GetAdorner(control) ?? AddAdorner(control);
if (adorner != null) adorner.Text = placeholderText;
}
else
{
RemoveAdorner(control);
}
}
private static void RegisterControl(Control control)
{
control.Loaded += OnControlLoaded;
var textBox = control as TextBoxBase;
if (textBox != null) RegisterTextBox(textBox);
}
private static void RegisterTextBox(TextBoxBase textBox)
{
textBox.GotKeyboardFocus += OnTextBoxGotKeyboardFocus;
textBox.LostKeyboardFocus += OnControlLoaded;
}
private static void UnregisterControl(Control control)
{
if (handledControls.Remove(control))
{
control.Loaded -= OnControlLoaded;
var textBox = control as TextBoxBase;
if (textBox != null) UnregisterTextBox(textBox);
RemoveAdorner(control);
}
}
private static void UnregisterTextBox(TextBoxBase textBox)
{
textBox.GotKeyboardFocus -= OnTextBoxGotKeyboardFocus;
textBox.LostKeyboardFocus -= OnControlLoaded;
}
private static bool IsEmpty(Control control)
{
var textBox = control as TextBox;
if (textBox != null) return string.IsNullOrEmpty(textBox.Text);
return false;
}
private static PlaceholderAdorner GetAdorner(Control control)
{
var layer = AdornerLayer.GetAdornerLayer(control);
if (layer != null)
{
var adorners = layer.GetAdorners(control);
if (adorners != null)
{
foreach (var adorner in adorners)
{
var placeholder = adorner as PlaceholderAdorner;
if (placeholder != null) return placeholder;
}
}
}
return null;
}
private static PlaceholderAdorner AddAdorner(Control control)
{
var layer = AdornerLayer.GetAdornerLayer(control);
if (layer == null) return null;
var placeholder = new PlaceholderAdorner(control);
layer.Add(placeholder);
return placeholder;
}
private static void RemoveAdorner(Control control)
{
var layer = AdornerLayer.GetAdornerLayer(control);
if (layer == null) return;
var adorners = layer.GetAdorners(control);
if (adorners == null) return;
foreach (var adorner in adorners)
{
var placeholder = adorner as PlaceholderAdorner;
if (placeholder != null)
{
layer.Remove(placeholder);
return;
}
}
}
}
}
@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace UnicodeCharacterInspector
{
internal static partial class Placeholder
{
private sealed class PlaceholderAdorner : Adorner
{
public string Text { get; set; }
public PlaceholderAdorner(UIElement adornedElement)
: base(adornedElement)
{
IsHitTestVisible = false;
}
protected override Visual GetVisualChild(int index) { throw new InvalidOperationException(); }
protected override int VisualChildrenCount { get { return 0; } }
protected override void OnRender(DrawingContext drawingContext)
{
var control = ((Control)AdornedElement);
Rect adornedElementRect = new Rect(AdornedElement.RenderSize);
drawingContext.DrawText
(
new FormattedText
(
Text,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface
(
control.FontFamily,
control.FontStyle,
control.FontWeight,
control.FontStretch,
SystemFonts.MessageFontFamily
),
control.FontSize,
SystemColors.GrayTextBrush
),
// The offsets where experimentally determined on a Windows 8.1 machine. I'm willing to accept anything better. 😉
new Point(control.BorderThickness.Left + control.Padding.Left + 5, control.BorderThickness.Top + control.Padding.Top + 3)
);
}
}
}
}
@@ -73,6 +73,10 @@
<Compile Include="BindableObject.cs" />
<Compile Include="CharacterInfoViewModel.cs" />
<Compile Include="CharacterInspectorViewModel.cs" />
<Compile Include="Placeholder.cs" />
<Compile Include="PlaceholderAdorner.cs">
<DependentUpon>Placeholder.cs</DependentUpon>
</Compile>
<Compile Include="ZeroToVisibilityConverter.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>