C
SOLO with code C# is very complex to achieve what you need, as it requires modifying the Template of TextBox to add functionalities that you do not have. I did it this way:First:You'll need to create a UserControl, you could TextBox directly, but the way I present it to you can reuse control as many times as you want, I called the "ModTextBox" control but you can give it the name you want.Create a new UserControl and on the XAML you must put this:<TextBox x:Class="TuProyecto.UserControls.ModTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d"
d:DesignHeight="23" d:DesignWidth="120" Margin="0" >
<TextBox.Resources>
<ResourceDictionary>
<SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>
</ResourceDictionary>
</TextBox.Resources>
<TextBox.Style>
<Style>
<Setter Property="TextBox.Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="TextBox.BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="TextBox.Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="TextBox.BorderThickness" Value="1"/>
<Setter Property="TextBox.Height" Value="23"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="TextBox.HorizontalContentAlignment" Value="Left"/>
<Setter Property="TextBox.FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="TextBox.AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="TextBox.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" CornerRadius="6" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Margin="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/>
<Label FontFamily="{Binding PlaceHolderFontFamily}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Visibility="{Binding PlaceHolderVisibility}" FontSize="{Binding PlaceHolderFontSize, TargetNullValue=12, FallbackValue=12}" Grid.Column="0" Content="{Binding PlaceHolderText, TargetNullValue='', FallbackValue=''}" x:Name="PART_PlaceHolderLabel" Focusable="false" Margin="0" Foreground="#FF8D8D8D" Padding="2,0,5,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="TextBox.IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="TextBox.IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="TextBox.SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Then in the UserControl code you place this:using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace TuProyecto.UserControls
{
/// <summary>
/// Lógica de interacción para ModTextBox.xaml
/// </summary>
public partial class ModTextBox : TextBox, INotifyPropertyChanged
{
#region Propiedades
[Category("ModTextBox")]
public FontFamily PlaceHolderFontFamily
{
get { return (FontFamily)GetValue(PlaceHolderFontFamilyProperty); }
set { SetValue(PlaceHolderFontFamilyProperty, value); }
}
// Using a DependencyProperty as the backing store for PlaceHolderFontFamily. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PlaceHolderFontFamilyProperty =
DependencyProperty.Register("PlaceHolderFontFamily", typeof(FontFamily), typeof(ModTextBox), new PropertyMetadata(new FontFamily("Segoe UI")));
[Category("ModTextBox")]
public string PlaceHolderText
{
get { return (string)GetValue(PlaceHolderTextProperty); }
set { SetValue(PlaceHolderTextProperty, value); }
}
// Using a DependencyProperty as the backing store for PlaceHolderText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PlaceHolderTextProperty =
DependencyProperty.Register("PlaceHolderText", typeof(string), typeof(ModTextBox), new PropertyMetadata("Texto"));
private static Brush DefaultPlaceHolderForeground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF8D8D8D"));
[Category("ModTextBox")]
public Brush PlaceHolderForeground
{
get { return (Brush)GetValue(PlaceHolderForegroundProperty); }
set { SetValue(PlaceHolderForegroundProperty, value); }
}
// Using a DependencyProperty as the backing store for PlaceHolderForeground. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PlaceHolderForegroundProperty =
DependencyProperty.Register("PlaceHolderForeground", typeof(Brush), typeof(ModTextBox), new PropertyMetadata(DefaultPlaceHolderForeground));
[Category("ModTextBox")]
public double PlaceHolderFontSize
{
get { return (double)GetValue(PlaceHolderFontSizeProperty); }
set { SetValue(PlaceHolderFontSizeProperty, value); }
}
// Using a DependencyProperty as the backing store for PlaceHolderFontSize. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PlaceHolderFontSizeProperty =
DependencyProperty.Register("PlaceHolderFontSize", typeof(double), typeof(ModTextBox), new PropertyMetadata((double)12));
[Category("ModTextBox")]
public Visibility PlaceHolderVisibility
{
get { return (Visibility)GetValue(PlaceHolderVisibilityProperty); }
set { SetValue(PlaceHolderVisibilityProperty, value); }
}
// Using a DependencyProperty as the backing store for PlaceHolderVisibility. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PlaceHolderVisibilityProperty =
DependencyProperty.Register("PlaceHolderVisibility", typeof(Visibility), typeof(ModTextBox), new PropertyMetadata(Visibility.Visible));
#endregion
public ModTextBox()
{
InitializeComponent();
this.DefaultStyleKey = typeof(ModTextBox);
TextChanged += ModTextBox_TextChanged;
}
void ModTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (Text.Length > 0)
{
PlaceHolderVisibility = System.Windows.Visibility.Collapsed;
}
else
{
PlaceHolderVisibility = System.Windows.Visibility.Visible;
}
}
#region Implementación de INotifyPropertyChanged
//Lo uso para la propiedad RemainText así no queda como DependencyProperty
//pero mantiene la notificación de cambios a la UI
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
}
Second:Now that you have it, you declare it in the window where you want to use it, in this case on MainWindow:<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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:controls="clr-namespace:TuProyecto.UserControls"
mc:Ignorable="d"
x:Class="TuProyecto.MainWindow"
Title="Tu Proyecto">
<Grid>
<controls:ModTextBox TextWrapping="Wrap" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Width="200" PlaceHolderText="Nombre de usuario"/>
</Grid>
</Window>
And that's it, a TextBox with curved edge and placeholderEven if that's an extra, you can ignore it if you want. Bye.