2011-09-15 8 views
76

예를 들어 Facebook에는 텍스트 상자가 비어있을 때 검색 텍스트 상자에 "검색"힌트 텍스트가 있습니다.WPF 텍스트 상자에 힌트 텍스트를 추가하려면 어떻게해야합니까?

WPF 텍스트 상자를 사용하여이 작업을 수행하는 방법 ?? WPF를 들어

Facebook's search textbox

+0

봅니다 "큐 배너"를 검색합니다. –

+0

@MAKKAM [이 MSDN 기사] (http://msdn.microsoft.com/en-us/library/bb775793%28v=vs.85%29.aspx#cue_banner)에서는 설명하지만 완료 방법은 표시하지 않습니다. –

+1

도 참조하십시오 http://stackoverflow.com/questions/833943/watermark-textbox-in-wpf – OneWorld

답변

-10

는 방법이 없습니다. 당신은 그것을 모방해야합니다. See this example. 부수적 인 해결 방법은 TextBox에서 상속받은 WinForms 사용자 정의 컨트롤을 호스팅하고 EM_SETCUEBANNER 메시지를 편집 컨트롤에 보내는 것입니다. 즉. 당신이의 WinForm 제어 방식을 호스팅 할 경우

[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); 
} 

또한, 이미 BitFlex 프레임 워크라는이 구현, 당신이 할 수있는 download for free here를 포함하는 프레임 워크를 가지고있다.

Here is an article 자세한 내용은 BitFlex 정보를 참조하십시오. 일반적으로 상자에서 나오지 않는 Windows 탐색기 스타일 컨트롤을 사용하려는 경우와 WPF가 핸들과 함께 작동하지 않기 때문에 Win32 나 기존 컨트롤을 쉽게 래퍼로 작성할 수는 없습니다. WinForms.

스크린 샷 : enter image description here

+1

와우, 좀 hackish 보이는 ... XAML로 사용자 정의 컨트롤을 만들 때 어떻게합니까? –

+0

그렇지 않습니다. 이것이 어떻게 이루어 졌는지입니다. 이것을 캡슐화하려면 사용자 정의 컨트롤과 CueText 속성을 만들고 Setter에서 SetCueText를 호출하십시오. –

+0

이 방법을 사용하려면 OP가 winforms 컨트롤을 호스팅해야합니다. 아니면 텍스트 상자를 처리 할 수있는 방법이 있습니까? –

5

당신은 텍스트 상자를 상속하여 사용자 정의 컨트롤을 만들어야합니다. 아래 링크는 검색 텍스트 상자 샘플에 대한 훌륭한 예입니다. ,

<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> 

Style의 재사용 성을 높이려면 : 당신은 Style 훨씬 더 쉽게 VisualBrush 일부 트리거와이 작업을 수행 할 수있는이

http://davidowens.wordpress.com/2009/02/18/wpf-search-text-box/

+0

링크 전용 답변은 권장하지 않습니다. –

129

에서 참조하시기 바랍니다 당신은 또한 실제 큐 배너 텍스트, 색, 방향 등을 제어하기위한 일련의 속성을 생성 할 수 있습니다.

+1

IsKeyboardFocused 대신 IsMouseCaptured를 사용하십시오. 그것이 바로 큐 배너가 반응하는 방법입니다. – Monstieur

+3

스타일 재사용 가능성을 높이기 위해 첨부 된 속성을 사용하는 방법에 대해 궁금한 사람이 있으면 다음을 참조하십시오. http://stackoverflow.com/a/650620/724944 – surfen

+0

@Kurian IsMouseCaptured는 큐를 마우스로 클릭 할 때만 사라지게하지만 나타납니다 다시 마우스 버튼을 놓습니다. 보기 좋지 않습니다. IsMouseOver는 좋지 않습니다 (키보드에는 포커스가 있지만 마우스 포인터는 다른 곳에 있습니다 => 큐 표시됨). 대부분의 큐 배너는 IsKeyboardFocused (예를 들어 Facebook)를 사용하며 괜찮다고 생각합니다. 다른 해결책은 두 트리거를 모두 사용하는 것입니다. (IsMouseOver 또는 IsKeyboardFocused) – surfen

10

집합에 의한 코드 숨김 텍스트 색상을 처음에는 회색으로 변경하고 키보드 포커스를 얻거나 잃는 이벤트 핸들러를 추가합니다. 그런 다음

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"; 
     } 
    } 
} 
+5

-1 코드 숨김으로 처리하기 때문에 컨트롤이 혼란스럽고 다른 컨트롤 로직과 간섭하지 않을 가능성이 높습니다. – AlexeiOst

0

가 나는 GOT 손실 포커스 이벤트 사용 :

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을 사용했습니다.

-2

나는 VisualBrush으로 이것을 수행하고 에있는 몇 가지 트리거는 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 특성 조정을 고려하십시오. 닷넷을 사용하고 '3.5

+0

'''를' ' –

+5

으로 변경하여 문제를 해결했습니다. 다른 게시물에 대한 응답. 답으로 질문에 완전한 해결책을 게시하십시오. –

+4

@ sellmeadog의 대답이 거의 정확하다고 생각한다면 거의 차이가없는 새로운 대답을 게시하는 대신이를 수정하는 것이 좋습니다. – 0xBADF00D

37

이 마이크로 소프트 (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> 
+0

흥미로운 접근 방식은 나 자신을 즉시 생각하지 않았을 것입니다. – itsmatt

+0

nice와 simple :) –

+1

TextBlock을 'IsHitTestVisible = "False"로 설정하면이 솔루션이 특히 잘 작동합니다. –

0
<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> 
0

또 다른 방법 ;-)

PasswordBox로도 사용할 수 있습니다. TextBox과 함께 사용하려면 PasswordChangedTextChanged으로 바꾸기 만하면됩니다.

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> 

코드 숨김 :

private void txtPassword_PasswordChanged(object sender, RoutedEventArgs e) 
{ 
    txtHintPassword.Visibility = Visibility.Visible; 
    if (txtPassword.Password.Length > 0) 
    { 
     txtHintPassword.Visibility = Visibility.Hidden; 
    } 
} 
1

당신은 매우 간단한 방법으로 할 수 있습니다. 아이디어는 텍스트 상자와 같은 위치에 레이블을 배치하는 것입니다. 텍스트 상자에 텍스트가없고 포커스가없는 경우 레이블이 표시됩니다.

<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" /> 

보너스 : ("InputText]를"= "자리 표시 자 텍스트를 여기에"비어있는 경우, 예를 들어) 당신이 당신의 텍스트 상자에 대한 기본 값이 데이터를 제출할 때를 설정 한 후 확인하십시오.

0

다른 솔루션은 MahApps.Metro와 같은 WPF 툴킷을 사용하는 것입니다. 텍스트 상자 워터 마크처럼, 많은 좋은 기능을 가지고 있습니다 :

Controls:TextBoxHelper.Watermark="Search..."

내가 한 번 같은 상황에있어 http://mahapps.com/controls/textbox.html

1

참조, 나는 방법 다음 그것을 해결. 가 난 단지 힌트 상자의 요구 사항을 충족 한, 당신은

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; 
     } 
    } 
관련 문제