技術
WPFでTextBoxにPlaceHolderを表示する
こんにちは!ソリューションセクションの日野です
弊社、開発に際して結構いろいろな言語を使用しています
私が使用した言語だけでもphp(laravel,cakePHP等)やC#、go言語と様々です
現在はC#でWPFを使ってアプリケーションを開発中です
WPFはWindowsアプリケーションより自由度が高く細かいデザインができるのが特徴です
ただ、自由度が高すぎで絶妙にやりたいことができない、やれるけどめっちゃ複雑。。。ということが多々あります
今回はWPFでTextBoxにPlaceHolderを表示したかったので拡張プロパティを作りました
最終的に以下のようになります
この「テスト」を表示するために拡張プロパティが必要です
ざっくり説明すると拡張プロパティのPlaceHolderに設定された文言をTextBoxの背景にするって感じになってます
ソースコード
PlaceholderTextBox.xaml
プレースホルダ―を表示するTextBoxの拡張クラスのソースです
class PlaceholderTextBox : TextBox
{
//プレースホルダ―用のプロパティを追加
public static readonly DependencyProperty PlaceholderProperty =
DependencyProperty.Register("Placeholder", typeof(string),
typeof(PlaceholderTextBox), new PropertyMetadata(null, OnPlaceHolderChanged));
private string _placeholder = string.Empty;
/// <summary>
/// プレースホルダーのプロパティを設定
/// </summary>
public string Placeholder
{
get
{
return _placeholder;
}
set
{
_placeholder = value;
}
}
/// <summary>
/// プレースホルダ―が変更されたときの変更
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void OnPlaceHolderChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var textBox = sender as TextBox;
if (textBox == null)
{
return;
}
//設定された文言をプレースホルダにいれます
var placeHolder = e.NewValue as string;
var handler = CreateEventHandler(placeHolder);
if (string.IsNullOrEmpty(placeHolder))
{
textBox.TextChanged -= handler;
}
else
{
textBox.TextChanged += handler;
if (string.IsNullOrEmpty(textBox.Text))
{
//プレースホルダ―の背景に文字列を設定します
textBox.Background = CreateVisualBrush(placeHolder);
}
}
}
/// <summary>
/// textChangedイベント作成
/// </summary>
/// <param name="placeHolder"></param>
/// <returns></returns>
private static TextChangedEventHandler CreateEventHandler(string placeHolder)
{
return (sender, e) =>
{
var textBox = (TextBox)sender;
if (string.IsNullOrEmpty(textBox.Text))
{
//Textが入力されていなければプレースホルダーを表示します
textBox.Background = CreateVisualBrush(placeHolder);
}
else
{
//Textが入力されたときに背景を真っ白にします
textBox.Background = new SolidColorBrush(Colors.White);
}
};
}
/// <summary>
/// 背景色を変更します
/// </summary>
/// <param name="placeHolder">PlaceHolderに設定された文言</param>
/// <returns>塗りつぶしの色を返します</returns>
private static VisualBrush CreateVisualBrush(string placeHolder)
{
//入力された文言でTextBlockを生成します
var visual = new TextBlock()
{
Text = placeHolder,
Padding = new Thickness(2, 1, 500, 1),
Foreground = new SolidColorBrush(Colors.LightGray),
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
Background = new SolidColorBrush(Colors.White)
};
//生成された塗りつぶしの色を返します
return new VisualBrush(visual)
{
Stretch = Stretch.None,
TileMode = TileMode.None,
AlignmentX = AlignmentX.Left,
AlignmentY = AlignmentY.Center,
};
}
/// <summary>
/// プレースホルダーをsetしたときの処理
/// </summary>
/// <param name="textbox">自分自身のTextBox</param>
/// <param name="placeHolder">PlaceHolderに設定された文言</param>
private static void SetPlaceHolderText(TextBox textbox, string placeHolder)
{
textbox.SetValue(PlaceholderProperty, placeHolder);
}
/// <summary>
/// プレースホルダー取得処理
/// </summary>
/// <param name="textBox"></param>
/// <returns>プレースホルダーで設定された文字を返します</returns>
public static string GetPlaceHolderText(TextBox textBox)
{
return textBox.GetValue(PlaceholderProperty) as string;
}
}
Window.xaml
上記の拡張クラスをWindowのXamlで呼びます
<local:PlaceholderTextBox Placeholder="テスト" Width="100" />
<local:PlaceholderTextBox Placeholder="テスト" Margin="0,50,0,0" Width="100" />
これでプレースホルダ―を表示できました!
HTMLであればInputタグで普通にPlaceholder属性が使用できるので
WPFでもこれくらい簡単にしてほしいところですね
今回はこの辺で!
それでは!!