developer tip

WPF 텍스트 상자에 힌트 텍스트를 추가하려면 어떻게해야합니까?

copycodes 2020. 8. 20. 18:59
반응형

WPF 텍스트 상자에 힌트 텍스트를 추가하려면 어떻게해야합니까?


예를 들어 Facebook은 텍스트 상자가 비어있을 때 검색 텍스트 상자에 "검색"힌트 텍스트가 있습니다.

WPF 텍스트 상자로 이것을 달성하는 방법 ??

Facebook의 검색 텍스트 상자


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>

이의 재사용 성을 높이기 위해 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>

처음에는 텍스트 색상을 회색으로 설정하고 키보드 포커스를 얻거나 잃는 이벤트 핸들러를 추가하여 코드 숨김에서 수행하십시오.

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/


materialDesign HintAssist 를 사용 하는 것은 어떻습니까? 나는 이것을 사용하고 있습니다. 또한 부동 힌트를 추가 할 수 있습니다.

<TextBox Width="150" Height="40" Text="hello" materialDesign:HintAssist.Hint="address"  materialDesign:HintAssist.IsFloating="True"></TextBox>

Nuget Package로 Material Design을 설치했습니다. 문서 링크에 설치 가이드가 있습니다.


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

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

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

또 다른 해결책은 MahApps.Metro와 같은 WPF 도구 키트를 사용하는 것입니다. 텍스트 상자 워터 마크와 같은 많은 멋진 기능이 있습니다.

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

http://mahapps.com/controls/textbox.html 참조


I accomplish this with a VisualBrush and some triggers in a Style suggested by :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 :Application running, bt Design not loading...the following Error comes: Ambiguous type reference. A type named 'StaticExtension' occurs in at least two namespaces, 'MS.Internal.Metadata.ExposedTypes.Xaml' and 'System.Windows.Markup'. Consider adjusting the assembly XmlnsDefinition attributes. 'm using .net 3.5


For WPF, there isn't a way. You have to mimic it. See this example. A secondary (flaky solution) is to host a WinForms user control that inherits from TextBox and send the EM_SETCUEBANNER message to the edit control. ie.

[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와 함께.

스크린 샷 : 여기에 이미지 설명 입력

참고 URL : https://stackoverflow.com/questions/7425618/how-can-i-add-a-hint-text-to-wpf-textbox

반응형