답변:
a VisualBrush
와 일부 트리거를 사용하면 이 작업을 훨씬 더 쉽게 수행 할 수 있습니다 Style
.
<TextBox>
<TextBox.Style>
<Style TargetType="TextBox" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="Search" Foreground="LightGray" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
this의 재사용 성을 높이기 위해 Style
실제 큐 배너 텍스트, 색상, 방향 등을 제어하는 연결된 속성 집합을 만들 수도 있습니다.
이것은 Microsoft ( https://code.msdn.microsoft.com/windowsapps/How-to-add-a-hint-text-to-ed66a3c6 ) 에서 채택한 간단한 솔루션입니다.
<Grid Background="White" HorizontalAlignment="Right" VerticalAlignment="Top" >
<!-- overlay with hint text -->
<TextBlock Margin="5,2" MinWidth="50" Text="Suche..."
Foreground="LightSteelBlue" Visibility="{Binding ElementName=txtSearchBox, Path=Text.IsEmpty, Converter={StaticResource MyBoolToVisibilityConverter}}" />
<!-- enter term here -->
<TextBox MinWidth="50" Name="txtSearchBox" Background="Transparent" />
</Grid>
IsHitTestVisible="False"
materialDesign HintAssist 를 사용 하는 것은 어떻습니까? 나는 이것을 사용하고 있습니다. 또한 부동 힌트를 추가 할 수 있습니다.
<TextBox Width="150" Height="40" Text="hello" materialDesign:HintAssist.Hint="address" materialDesign:HintAssist.IsFloating="True"></TextBox>
Nuget Package로 Material Design을 설치했습니다. 문서 링크에 설치 가이드가 있습니다.
처음에는 텍스트 색상을 회색으로 설정하고 키보드 포커스를 얻거나 잃는 이벤트 핸들러를 추가하여 코드 숨김에서 수행하십시오.
TextBox tb = new TextBox();
tb.Foreground = Brushes.Gray;
tb.Text = "Text";
tb.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(tb_GotKeyboardFocus);
tb.LostKeyboardFocus += new KeyboardFocusChangedEventHandler(tb_LostKeyboardFocus);
그런 다음 이벤트 핸들러 :
private void tb_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
if(sender is TextBox)
{
//If nothing has been entered yet.
if(((TextBox)sender).Foreground == Brushes.Gray)
{
((TextBox)sender).Text = "";
((TextBox)sender).Foreground = Brushes.Black;
}
}
}
private void tb_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
//Make sure sender is the correct Control.
if(sender is TextBox)
{
//If nothing was entered, reset default text.
if(((TextBox)sender).Text.Trim().Equals(""))
{
((TextBox)sender).Foreground = Brushes.Gray;
((TextBox)sender).Text = "Text";
}
}
}
텍스트 상자를 상속하여 사용자 지정 컨트롤을 만들어야합니다. 아래 링크에는 검색 텍스트 상자 샘플에 대한 훌륭한 예가 있습니다. 이것 좀 봐주세요
http://davidowens.wordpress.com/2009/02/18/wpf-search-text-box/
아주 간단한 방법으로 할 수 있습니다. 아이디어는 텍스트 상자와 같은 위치에 레이블을 배치하는 것입니다. 텍스트 상자에 텍스트가없고 포커스가없는 경우 레이블이 표시됩니다.
<Label Name="PalceHolder" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Height="40" VerticalAlignment="Top" Width="239" FontStyle="Italic" Foreground="BurlyWood">PlaceHolder Text Here
<Label.Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding ="{Binding ElementName=PalceHolder, Path=Text.Length}" Value="0"/>
<Condition Binding ="{Binding ElementName=PalceHolder, Path=IsFocused}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
<TextBox Background="Transparent" Name="TextBox1" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Height="40"TextWrapping="Wrap" Text="{Binding InputText,Mode=TwoWay}" VerticalAlignment="Top" Width="239" />
보너스 : textBox에 대한 기본값을 원하면 데이터를 제출할 때 설정해야합니다 (예 : 비어있는 경우 "InputText"= "PlaceHolder Text Here").
또 다른 접근 방식 ;-)
이것은 PasswordBox
. 와 함께 사용하려면로 TextBox
교환 PasswordChanged
하면 TextChanged
됩니다.
XAML :
<Grid>
<!-- overlay with hint text -->
<TextBlock Margin="5,2"
Text="Password"
Foreground="Gray"
Name="txtHintPassword"/>
<!-- enter user here -->
<PasswordBox Name="txtPassword"
Background="Transparent"
PasswordChanged="txtPassword_PasswordChanged"/>
</Grid>
CodeBehind :
private void txtPassword_PasswordChanged(object sender, RoutedEventArgs e)
{
txtHintPassword.Visibility = Visibility.Visible;
if (txtPassword.Password.Length > 0)
{
txtHintPassword.Visibility = Visibility.Hidden;
}
}
나는 한때 같은 상황에 들어갔고 다음과 같이 해결했습니다. 힌트 상자의 요구 사항 만 충족했습니다. 포커스 등의 다른 이벤트에 효과 및 기타 사항을 추가하여 더 상호 작용하도록 만들 수 있습니다.
WPF 코드 (읽을 수 있도록 스타일을 제거했습니다)
<Grid Margin="0,0,0,0" Background="White">
<Label Name="adminEmailHint" Foreground="LightGray" Padding="6" FontSize="14">Admin Email</Label>
<TextBox Padding="4,7,4,8" Background="Transparent" TextChanged="adminEmail_TextChanged" Height="31" x:Name="adminEmail" Width="180" />
</Grid>
<Grid Margin="10,0,10,0" Background="White" >
<Label Name="adminPasswordHint" Foreground="LightGray" Padding="6" FontSize="14">Admin Password</Label>
<PasswordBox Padding="4,6,4,8" Background="Transparent" PasswordChanged="adminPassword_PasswordChanged" Height="31" x:Name="adminPassword" VerticalContentAlignment="Center" VerticalAlignment="Center" Width="180" FontFamily="Helvetica" FontWeight="Light" FontSize="14" Controls:TextBoxHelper.Watermark="Admin Password" FontStyle="Normal" />
</Grid>
C # 코드
private void adminEmail_TextChanged(object sender, TextChangedEventArgs e)
{
if(adminEmail.Text.Length == 0)
{
adminEmailHint.Visibility = Visibility.Visible;
}
else
{
adminEmailHint.Visibility = Visibility.Hidden;
}
}
private void adminPassword_PasswordChanged(object sender, RoutedEventArgs e)
{
if (adminPassword.Password.Length == 0)
{
adminPasswordHint.Visibility = Visibility.Visible;
}
else
{
adminPasswordHint.Visibility = Visibility.Hidden;
}
}
또 다른 해결책은 MahApps.Metro와 같은 WPF 도구 키트를 사용하는 것입니다. 텍스트 상자 워터 마크와 같은 많은 멋진 기능이 있습니다.
Controls:TextBoxHelper.Watermark="Search..."
나는 got 및 lost focus 이벤트를 사용했습니다.
Private Sub txtSearchBox_GotFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles txtSearchBox.GotFocus
If txtSearchBox.Text = "Search" Then
txtSearchBox.Text = ""
Else
End If
End Sub
Private Sub txtSearchBox_LostFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles txtSearchBox.LostFocus
If txtSearchBox.Text = "" Then
txtSearchBox.Text = "Search"
Else
End If
End Sub
잘 작동하지만 텍스트는 여전히 회색입니다. 청소가 필요합니다. VB.NET을 사용하고있었습니다.
<Grid>
<TextBox Name="myTextBox"/>
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=myTextBox, Path=Text.IsEmpty}" Value="True">
<Setter Property="Text" Value="Prompt..."/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
그게 내 생각입니다.
<ControlTemplate>
<Grid>
<Grid.Resources>
<!--Define look / layout for both TextBoxes here. I applied custom Padding and BorderThickness for my application-->
<Style TargetType="TextBox">
<Setter Property="Padding" Value="4"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Grid.Resources>
<TextBox x:Name="TbSearch"/>
<TextBox x:Name="TbHint" Text="Suche" Foreground="LightGray"
Visibility="Hidden" IsHitTestVisible="False" Focusable="False"/>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition SourceName="TbSearch" Property="Text" Value="{x:Static sys:String.Empty}"/>
<Condition SourceName="TbSearch" Property="IsKeyboardFocused" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="TbHint" Property="Visibility" Value="Visible"/>
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition SourceName="TbSearch" Property="Text" Value="{x:Null}"/>
<Condition SourceName="TbSearch" Property="IsKeyboardFocused" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="TbHint" Property="Visibility" Value="Visible"/>
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
상위 답변을 포함한 대부분의 다른 답변에는 제 생각에 결함이 있습니다.
이 솔루션은 모든 상황에서 작동합니다. 순수한 XAML, 쉽게 재사용 할 수 있습니다.
나는 a VisualBrush
및에 의해 Style
제안 된 몇 가지 트리거로 이것을 수행합니다 sellmeadog
.
<TextBox>
<TextBox.Style>
<Style TargetType="TextBox" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="Search" Foreground="LightGray" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
@sellmeadog : 응용 프로그램 실행 중, bt 디자인이로드되지 않음 ... 다음 오류가 발생합니다. 모호한 형식 참조. 'StaticExtension'이라는 형식은 'MS.Internal.Metadata.ExposedTypes.Xaml'및 'System.Windows.Markup'이라는 두 개 이상의 네임 스페이스에서 발생합니다. 어셈블리 XmlnsDefinition 특성 조정을 고려하십시오. .net 3.5를 사용하고 있습니다.
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
에<Trigger Property="Text" Value="">
WPF의 경우 방법이 없습니다. 당신은 그것을 모방해야합니다. 이 예를 참조하십시오 . 두 번째 (변칙적 인 솔루션)은 TextBox에서 상속 된 WinForms 사용자 정의 컨트롤을 호스팅하고 EM_SETCUEBANNER 메시지를 편집 컨트롤로 보내는 것입니다. 즉.
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam);
private const Int32 ECM_FIRST = 0x1500;
private const Int32 EM_SETCUEBANNER = ECM_FIRST + 1;
private void SetCueText(IntPtr handle, string cueText) {
SendMessage(handle, EM_SETCUEBANNER, IntPtr.Zero, Marshal.StringToBSTR(cueText));
}
public string CueText {
get {
return m_CueText;
}
set {
m_CueText = value;
SetCueText(this.Handle, m_CueText);
}
또한 WinForm 컨트롤 접근 방식을 호스팅하려는 경우 BitFlex Framework라는이 구현이 이미 포함 된 프레임 워크가 있습니다 . 여기에서 무료로 다운로드 할 수 있습니다 .
다음은 기사입니다 좀 더 자세한 정보를 원하는 경우 BitFlex에 대한이. Windows 탐색기 스타일 컨트롤을 사용하려는 경우 일반적으로 기본적으로 제공되지 않으며 WPF가 일반적으로 핸들과 함께 작동하지 않기 때문에 Win32 또는 기존 컨트롤에 대한 쉬운 래퍼를 작성할 수 없다는 사실을 알게 될 것입니다. WinForms와 함께.
스크린 샷 :