Наприклад, Facebook має текст підказки "Пошук" у текстовому полі "Пошук", коли текстове поле порожнє.
Як цього досягти за допомогою текстових полів WPF ??
Наприклад, Facebook має текст підказки "Пошук" у текстовому полі "Пошук", коли текстове поле порожнє.
Як цього досягти за допомогою текстових полів WPF ??
Відповіді:
Ви можете зробити це набагато простіше за допомогою 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>
IsHitTestVisible="False"
як щодо використання materialDesign HintAssist? Я використовую це, що також ви можете додати плаваючу підказку:
<TextBox Width="150" Height="40" Text="hello" materialDesign:HintAssist.Hint="address" materialDesign:HintAssist.IsFloating="True"></TextBox>
я встановив Material Design за допомогою Nuget Package, у посиланні на документацію є посібник з установки
Зробіть це за допомогою коду, встановивши колір тексту спочатку сірий та додавши обробники подій для отримання та втрати фокусу на клавіатурі.
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" = "Тут розміщено текст тексту", якщо порожній).
Інший підхід ;-)
це також працює з 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;
}
}
Іншим рішенням є використання інструментарію WPF на зразок MahApps.Metro. Він має багато приємних функцій, як водяний знак текстового поля:
Controls:TextBoxHelper.Watermark="Search..."
Я використовував отримані та втрачені фокус події:
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, легко використовувати багаторазово.
Я роблю це з 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 немає способу. Ви повинні наслідувати це. Дивіться цей приклад . Вторинним (лускатим рішенням) є розміщення керування користувачами WinForms, яке успадковується від TextBox та відправляє повідомлення 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 Explorer, що це, як правило, ніколи не виходить з коробки, і тому що WPF не працює з ручками, як правило, ви не можете написати простий обгортку навколо Win32 або наявний елемент управління, як ви можете. з WinForms.
Знімок екрана: