Ví dụ: Facebook có văn bản gợi ý "Tìm kiếm" trong hộp văn bản Tìm kiếm khi hộp văn bản trống.
Làm thế nào để đạt được điều này với các hộp văn bản WPF ??
Ví dụ: Facebook có văn bản gợi ý "Tìm kiếm" trong hộp văn bản Tìm kiếm khi hộp văn bản trống.
Làm thế nào để đạt được điều này với các hộp văn bản WPF ??
Câu trả lời:
Bạn có thể thực hiện điều này dễ dàng hơn nhiều với một VisualBrush
và một số trình kích hoạt trong 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>
Để tăng khả năng tái sử dụng của điều này Style
, bạn cũng có thể tạo một tập hợp các thuộc tính đính kèm để kiểm soát văn bản biểu ngữ gợi ý thực tế, màu sắc, hướng, v.v.
Đây là giải pháp đơn giản của tôi, được điều chỉnh từ 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"
còn việc sử dụng materialDesign HintAssist thì sao? Tôi đang sử dụng cái này, bạn cũng có thể thêm gợi ý nổi:
<TextBox Width="150" Height="40" Text="hello" materialDesign:HintAssist.Hint="address" materialDesign:HintAssist.IsFloating="True"></TextBox>
Tôi đã cài đặt Material Design với Nuget Package có hướng dẫn cài đặt trong liên kết tài liệu
Thực hiện điều đó ở đoạn mã phía sau bằng cách đặt màu văn bản ban đầu thành màu xám và thêm trình xử lý sự kiện để tăng và mất tiêu điểm bàn phím.
TextBox tb = new TextBox();
tb.Foreground = Brushes.Gray;
tb.Text = "Text";
tb.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(tb_GotKeyboardFocus);
tb.LostKeyboardFocus += new KeyboardFocusChangedEventHandler(tb_LostKeyboardFocus);
Sau đó, các trình xử lý sự kiện:
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";
}
}
}
Bạn phải tạo điều khiển tùy chỉnh bằng cách kế thừa hộp văn bản. Liên kết dưới đây có một ví dụ tuyệt vời về mẫu hộp văn bản tìm kiếm. Hãy xem cái này
http://davidowens.wordpress.com/2009/02/18/wpf-search-text-box/
Bạn có thể làm một cách rất đơn giản. Ý tưởng là đặt Nhãn ở cùng vị trí với hộp văn bản của bạn. Nhãn của bạn sẽ hiển thị nếu hộp văn bản không có văn bản và không có tiêu điểm.
<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" />
Phần thưởng: Nếu bạn muốn đặt giá trị mặc định cho textBox của mình, hãy đảm bảo sau khi đặt giá trị đó khi gửi dữ liệu (ví dụ: "InputText" = "PlaceHolder Text Here" nếu trống).
Cách tiếp cận khác ;-)
điều này cũng hoạt động với PasswordBox
. Nếu bạn muốn sử dụng nó TextBox
, chỉ cần trao đổi PasswordChanged
với 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>
Mã ẩn:
private void txtPassword_PasswordChanged(object sender, RoutedEventArgs e)
{
txtHintPassword.Visibility = Visibility.Visible;
if (txtPassword.Password.Length > 0)
{
txtHintPassword.Visibility = Visibility.Hidden;
}
}
Tôi đã từng rơi vào trường hợp tương tự, tôi đã giải quyết nó theo cách sau. Tôi chỉ đáp ứng các yêu cầu của hộp gợi ý, bạn có thể làm cho nó tương tác hơn bằng cách thêm hiệu ứng và những thứ khác vào các sự kiện khác như tiêu điểm, v.v.
WPF CODE (Tôi đã xóa kiểu để làm cho nó có thể đọc được)
<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>
Mã 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;
}
}
Một giải pháp khác là sử dụng bộ công cụ WPF như MahApps.Metro. Nó có nhiều tính năng hay, như hình mờ hộp văn bản:
Controls:TextBoxHelper.Watermark="Search..."
Tôi đã sử dụng các sự kiện được và mất tiêu điểm:
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
Nó hoạt động tốt, nhưng văn bản vẫn có màu xám. Cần dọn dẹp. Tôi đã sử dụng 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>
Đó là lý do của tôi:
<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>
Theo quan điểm của tôi, hầu hết các câu trả lời khác bao gồm cả câu trả lời hàng đầu đều có sai sót.
Giải pháp này hoạt động trong mọi trường hợp. XAML tinh khiết, dễ dàng tái sử dụng.
Tôi thực hiện điều này với một VisualBrush
và một số trigger trong một Style
đề xuất bởi: 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: Ứng dụng đang chạy, bt Thiết kế không tải ... lỗi sau xuất hiện: Tham chiếu kiểu không rõ ràng. Một kiểu có tên 'StaticExtension' xuất hiện trong ít nhất hai không gian tên, 'MS.Internal.Metadata.ExposedTypes.Xaml' và 'System.Windows.Markup'. Xem xét điều chỉnh các thuộc tính assembly XmlnsDefinition. đang sử dụng .net 3.5
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
thành<Trigger Property="Text" Value="">
Đối với WPF, không có cách nào. Bạn phải bắt chước nó. Hãy xem ví dụ này . Giải pháp thứ cấp (giải pháp không ổn định) là lưu trữ điều khiển người dùng WinForms kế thừa từ TextBox và gửi thông báo EM_SETCUEBANNER tới điều khiển chỉnh sửa. I E.
[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);
}
Ngoài ra, nếu bạn muốn lưu trữ phương pháp điều khiển WinForm, tôi có một khuôn khổ đã bao gồm triển khai này được gọi là BitFlex Framework, bạn có thể tải xuống miễn phí tại đây .
Đây là một bài báo về BitFlex nếu bạn muốn biết thêm thông tin. Bạn sẽ bắt đầu thấy rằng nếu bạn đang muốn có các điều khiển kiểu Windows Explorer mà điều này thường không bao giờ xuất hiện trong hộp và vì WPF không hoạt động với các tay cầm nên thường bạn không thể viết một trình bao bọc dễ dàng xung quanh Win32 hoặc một điều khiển hiện có như bạn có thể với WinForms.
Ảnh chụp màn hình: