html5의 텍스트 상자로 할 수있는 것처럼 텍스트 상자에 자리 표시 자 텍스트를 추가하는 방법을 찾고 있습니다.
즉, 텍스트 상자에 텍스트가 없으면 텍스트를 추가하고 Enter some text here
사용자 가 텍스트를 클릭하면 자리 표시 자 텍스트가 사라지고 사용자가 자신의 텍스트를 입력 할 수 있으며 텍스트 상자에 포커스가없고 텍스트가없는 경우 자리 표시자는 텍스트 상자에 다시 추가되었습니다.
답변
그것은 단지 다음과 같지 않을 것입니다 :
Textbox myTxtbx = new Textbox();
myTxtbx.Text = "Enter text here...";
myTxtbx.GotFocus += GotFocus.EventHandle(RemoveText);
myTxtbx.LostFocus += LostFocus.EventHandle(AddText);
public void RemoveText(object sender, EventArgs e)
{
if (myTxtbx.Text == "Enter text here...")
{
myTxtbx.Text = "";
}
}
public void AddText(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(myTxtbx.Text))
myTxtbx.Text = "Enter text here...";
}
그것은 의사 코드 일 뿐이지 만 개념이 있습니다.
답변
당신은 이것을 사용할 수 있습니다, 그것은 나를 위해 일하고 있으며 매우 간단한 해결책입니다.
<Style x:Key="placeHolder" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
Panel.ZIndex="2" />
<TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
용법:
<TextBox Style="{StaticResource placeHolder}" Tag="Name of customer" Width="150" Height="24"/>
답변
자리 표시 자 텍스트를 설정하고 제거하기 위해 포커스 입력 및 포커스 휴가 이벤트를 처리하는 대신 Windows SendMessage 함수를 사용하여 EM_SETCUEBANNER
텍스트 상자에 메시지를 보내서 작업을 수행 할 수 있습니다.
이것은 두 가지 쉬운 단계로 수행 할 수 있습니다. 먼저 Windows SendMessage
기능 을 공개해야 합니다.
private const int EM_SETCUEBANNER = 0x1501;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)]string lParam);
그런 다음 텍스트 상자의 핸들, EM_SETCUEBANNER의 값 및 설정하려는 텍스트로 메소드를 호출하십시오.
SendMessage(textBox1.Handle, EM_SETCUEBANNER, 0, "Username");
SendMessage(textBox2.Handle, EM_SETCUEBANNER, 0, "Password");
답변
이 클래스를 프로젝트에 추가하고 솔루션을 빌드하십시오. Visual Studio에서 도구 상자를 클릭하면 PlaceholderTextBox라는 새 텍스트 상자 구성 요소가 표시됩니다. 양식 디자인에서 현재 텍스트 상자를 삭제하고 PlaceHolderTextBox로 바꿉니다.
PlaceHolderTextBox에는 PlaceHolderText 속성이 있습니다. 원하는 텍스트를 설정하고 좋은 하루 되세요 🙂
public class PlaceHolderTextBox : TextBox
{
bool isPlaceHolder = true;
string _placeHolderText;
public string PlaceHolderText
{
get { return _placeHolderText; }
set
{
_placeHolderText = value;
setPlaceholder();
}
}
public new string Text
{
get => isPlaceHolder ? string.Empty : base.Text;
set => base.Text = value;
}
//when the control loses focus, the placeholder is shown
private void setPlaceholder()
{
if (string.IsNullOrEmpty(base.Text))
{
base.Text = PlaceHolderText;
this.ForeColor = Color.Gray;
this.Font = new Font(this.Font, FontStyle.Italic);
isPlaceHolder = true;
}
}
//when the control is focused, the placeholder is removed
private void removePlaceHolder()
{
if (isPlaceHolder)
{
base.Text = "";
this.ForeColor = System.Drawing.SystemColors.WindowText;
this.Font = new Font(this.Font, FontStyle.Regular);
isPlaceHolder = false;
}
}
public PlaceHolderTextBox()
{
GotFocus += removePlaceHolder;
LostFocus += setPlaceholder;
}
private void setPlaceholder(object sender, EventArgs e)
{
setPlaceholder();
}
private void removePlaceHolder(object sender, EventArgs e)
{
removePlaceHolder();
}
}
답변
이것은 내 코드는 아니지만 많이 사용하고 완벽하게 작동합니다 … XAML 만
<TextBox x:Name="Textbox" Height="23" Margin="0,17,18.8,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" HorizontalAlignment="Right" ></TextBox>
<TextBlock x:Name="Placeholder" IsHitTestVisible="False" TextWrapping="Wrap" Text="Placeholder Text" VerticalAlignment="Top" Margin="0,20,298.8,0" Foreground="DarkGray" HorizontalAlignment="Right" Width="214">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=Textbox}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
답변
구조에 부착 된 속성 :
public static class TextboxExtensions
{
public static readonly DependencyProperty PlaceholderProperty =
DependencyProperty.RegisterAttached(
"Placeholder",
typeof(string),
typeof(TextboxExtensions),
new PropertyMetadata(default(string), propertyChangedCallback: PlaceholderChanged)
);
private static void PlaceholderChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
var tb = dependencyObject as TextBox;
if (tb == null)
return;
tb.LostFocus -= OnLostFocus;
tb.GotFocus -= OnGotFocus;
if (args.NewValue != null)
{
tb.GotFocus += OnGotFocus;
tb.LostFocus += OnLostFocus;
}
SetPlaceholder(dependencyObject, args.NewValue as string);
if (!tb.IsFocused)
ShowPlaceholder(tb);
}
private static void OnLostFocus(object sender, RoutedEventArgs routedEventArgs)
{
ShowPlaceholder(sender as TextBox);
}
private static void OnGotFocus(object sender, RoutedEventArgs routedEventArgs)
{
HidePlaceholder(sender as TextBox);
}
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static void SetPlaceholder(DependencyObject element, string value)
{
element.SetValue(PlaceholderProperty, value);
}
[AttachedPropertyBrowsableForType(typeof(TextBox))]
public static string GetPlaceholder(DependencyObject element)
{
return (string)element.GetValue(PlaceholderProperty);
}
private static void ShowPlaceholder(TextBox textBox)
{
if (string.IsNullOrWhiteSpace(textBox.Text))
{
textBox.Text = GetPlaceholder(textBox);
}
}
private static void HidePlaceholder(TextBox textBox)
{
string placeholderText = GetPlaceholder(textBox);
if (textBox.Text == placeholderText)
textBox.Text = string.Empty;
}
}
용법:
<TextBox Text="hi" local:TextboxExtensions.Placeholder="Hello there"></TextBox>
답변
EM_SETCUEBANNER
메시지를 사용하는 것이 가장 간단 하지만 컨트롤이 포커스를 받으면 자리 표시 자 텍스트가 사라진다는 점이 마음에 들지 않습니다. 내가 양식을 작성할 때 그것은 내 애완 동물입니다. 필드가 무엇인지 기억하기 위해 그것을 클릭해야합니다.
WinForms를위한 또 다른 솔루션이 있습니다. Label
컨트롤 위에 a 를 오버레이 하여 사용자가 입력을 시작할 때만 사라집니다.
확실히 방탄은 아닙니다. 그것은 모든 것을 받아들이지 Control
만, 나는 단지로 테스트했다 TextBox
. 일부 컨트롤을 사용하려면 수정이 필요할 수 있습니다. Label
특정 경우에 약간 수정해야 할 경우이 메서드는 컨트롤을 반환 하지만 절대로 필요하지 않을 수도 있습니다.
다음과 같이 사용하십시오.
SetPlaceholder(txtSearch, "Type what you're searching for");
방법은 다음과 같습니다.
/// <summary>
/// Sets placeholder text on a control (may not work for some controls)
/// </summary>
/// <param name="control">The control to set the placeholder on</param>
/// <param name="text">The text to display as the placeholder</param>
/// <returns>The newly-created placeholder Label</returns>
public static Label SetPlaceholder(Control control, string text) {
var placeholder = new Label {
Text = text,
Font = control.Font,
ForeColor = Color.Gray,
BackColor = Color.Transparent,
Cursor = Cursors.IBeam,
Margin = Padding.Empty,
//get rid of the left margin that all labels have
FlatStyle = FlatStyle.System,
AutoSize = false,
//Leave 1px on the left so we can see the blinking cursor
Size = new Size(control.Size.Width - 1, control.Size.Height),
Location = new Point(control.Location.X + 1, control.Location.Y)
};
//when clicking on the label, pass focus to the control
placeholder.Click += (sender, args) => { control.Focus(); };
//disappear when the user starts typing
control.TextChanged += (sender, args) => {
placeholder.Visible = string.IsNullOrEmpty(control.Text);
};
//stay the same size/location as the control
EventHandler updateSize = (sender, args) => {
placeholder.Location = new Point(control.Location.X + 1, control.Location.Y);
placeholder.Size = new Size(control.Size.Width - 1, control.Size.Height);
};
control.SizeChanged += updateSize;
control.LocationChanged += updateSize;
control.Parent.Controls.Add(placeholder);
placeholder.BringToFront();
return placeholder;
}
