2011-09-15 29 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メッセージを編集コントロールに送信することです。すなわち、あなたはWinフォームコントロールアプローチをホストする場合

[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についての情報をご覧ください。これは、一般的にボックスの外に出てこないWPFがハンドルでは動作しないため、Windowsエクスプローラのスタイルコントロールを使用する場合、Win32や既存のコントロールを簡単に記述することはできませんWinFormsで。

スクリーンショット: enter image description here

+1

うわー、それはちょっとハッキリしています。どうすればXAMLでユーザーコントロールを作成できますか? –

+0

あなたはそうではありません。これはそれがどのように行われるかです。これをカプセル化したい場合は、ユーザーコントロールとCueTextプロパティを作成し、setterでSetCueTextを呼び出します。 –

+0

私は、このアプローチを使用するには、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の再利用性を高めるために: はあなたがVisualBrushStyleでいくつかのトリガーとはるかに簡単にこれを達成することができます。この

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

@クリアン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

私が持って、失われたフォーカスイベントを使用:

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でこれを実現し、で示唆された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> 

@sellmeadog:アプリケーションの実行中、BTのデザインはロードしていない...次のエラーが来る: あいまいなタイプの参照を。 'StaticExtension'という名前の型は、少なくとも2つの名前空間、 'MS.Internal.Metadata.ExposedTypes.Xaml'と 'System.Windows.Markup'で発生します。アセンブリのXmlnsDefinition属性を調整することを検討してください。 は、.NETに使用してM」3.5

+0

'を '<' Trigger Property = "Text" Value = ""> ' –

+5

に変更して問題を解決しました。別の投稿への返信回答として質問に完全な解決策を投稿してください。 –

+4

@ sellmeadogの答えがほぼ正しいと思うならば、ほとんど差がなく新しい回答を投稿するのではなく、修正することを検討してください。 – 0xBADF00D

37

これは、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> 
+0

面白いアプローチ私はすぐに自分自身を考えていないでしょう。 – itsmatt

+0

素敵でシンプル:) –

+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

もう1つの解決策は、MahApps.MetroのようなWPFツールキットを使用することです。これは、テキストボックス透かしのように、多くの素晴らしい機能を持っています

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

は、私がかつて同じような状況に陥ったhttp://mahapps.com/controls/textbox.html

1

、私は道以下にそれを解決し参照してください。 は、私が唯一のヒントボックスの要件を満たしてきた、あなたは

WPFのCODEは(私はそれを作るためにスタイリングを削除したなどのフォーカスのような他のイベントへの影響や他のものを追加することによって、それをよりインタラクティブにすることができます読める)

<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; 
     } 
    } 
関連する問題