Örneğin, Facebook, metin kutusu boşken Ara metin kutusunda bir "Ara" ipucu metnine sahiptir.
Bunu WPF metin kutuları ile nasıl başarabilirim?

Örneğin, Facebook, metin kutusu boşken Ara metin kutusunda bir "Ara" ipucu metnine sahiptir.
Bunu WPF metin kutuları ile nasıl başarabilirim?

Yanıtlar:
Bunu a VisualBrushve a'daki bazı tetikleyicilerle çok daha kolay bir şekilde başarabilirsiniz 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>
Bunun yeniden kullanılabilirliğini artırmak için Style, gerçek geçiş afiş metnini, rengini, yönünü vb. Kontrol etmek için bir dizi ek özellik de oluşturabilirsiniz.
Bu, Microsoft'tan uyarlanmış basit çözümümdür ( 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'i kullanmaya ne dersiniz? Ben bunu kullanıyorum, ayrıca kayan ipucu da ekleyebilirsiniz:
<TextBox Width="150" Height="40" Text="hello" materialDesign:HintAssist.Hint="address" materialDesign:HintAssist.IsFloating="True"></TextBox>
Material Design'ı Nuget Paketi ile kurdum, dokümantasyon bağlantısında kurulum kılavuzu var
Metin rengini başlangıçta gri olarak ayarlayarak ve klavye odağını kazanmak ve kaybetmek için olay işleyicileri ekleyerek arka planda kodlama yapın.
TextBox tb = new TextBox();
tb.Foreground = Brushes.Gray;
tb.Text = "Text";
tb.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(tb_GotKeyboardFocus);
tb.LostKeyboardFocus += new KeyboardFocusChangedEventHandler(tb_LostKeyboardFocus);
Ardından olay işleyicileri:
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";
}
}
}
Metin kutusunu miras alarak özel bir kontrol oluşturmanız gerekir. Aşağıdaki bağlantıda arama metin kutusu örneği hakkında mükemmel bir örnek var. Lütfen şuna bir bak
http://davidowens.wordpress.com/2009/02/18/wpf-search-text-box/
Çok basit bir şekilde yapabilirsiniz. Buradaki fikir, metin kutunuzla aynı yere bir Etiket yerleştirmektir. Metin kutusunda metin yoksa ve odak yoksa Etiketiniz görünür olacaktır.
<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" />
Bonus: Metin Kutunuz için varsayılan değere sahip olmak istiyorsanız, veri gönderirken bunu ayarladığınızdan emin olun (örneğin: "InputText" = "Boşsa" Yer Tutucu Metni Buraya Yerleştirin ").
Başka bir yaklaşım ;-)
bu aynı zamanda ile de çalışır PasswordBox. Eğer bunu kullanmak istiyorsanız TextBox, basitçe alışverişinde PasswordChangedile 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>
Kodun arkasında:
private void txtPassword_PasswordChanged(object sender, RoutedEventArgs e)
{
txtHintPassword.Visibility = Visibility.Visible;
if (txtPassword.Password.Length > 0)
{
txtHintPassword.Visibility = Visibility.Hidden;
}
}
Bir keresinde aynı duruma girdim, şu şekilde çözdüm. Sadece bir ipucu kutusunun gereksinimlerini yerine getirdim, odaklanma gibi diğer olaylara efektler ve başka şeyler ekleyerek onu daha etkileşimli hale getirebilirsiniz.
WPF KODU (Okunabilir hale getirmek için stili kaldırdım)
<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 # Kodu
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;
}
}
Başka bir çözüm de MahApps.Metro gibi bir WPF araç seti kullanmaktır. Metin kutusu filigranı gibi birçok güzel özelliğe sahiptir:
Controls:TextBoxHelper.Watermark="Search..."
Var ve kaybolan odak olaylarını kullandı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
İyi çalışıyor, ancak metin hala gri renkte. Temizlenmesi gerekiyor. VB.NET kullanıyordum
<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>
Benim alacağım:
<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>
En iyisi de dahil olmak üzere diğer cevapların çoğunun bence kusurları var.
Bu çözüm her koşulda işe yarar. Saf XAML, kolayca yeniden kullanılabilir.
Ben ile bunu gerçekleştirmek VisualBrushve bazı tetikleyiciler Styleönerdiğ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: Uygulama çalışıyor, bt Tasarım yüklenmiyor ... Şu Hata geliyor: Belirsiz tür başvurusu. 'StaticExtension' adlı bir tür, en az iki ad alanında bulunur, 'MS.Internal.Metadata.ExposedTypes.Xaml' ve 'System.Windows.Markup'. Assembly XmlnsDefinition özniteliklerini ayarlamayı düşünün. .net 3.5 kullanıyorum
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">için<Trigger Property="Text" Value="">
WPF için bir yol yok. Onu taklit etmelisin. Bu örneğe bakın . İkincil (hatalı çözüm), TextBox'tan devralan bir WinForms kullanıcı kontrolünü barındırmak ve EM_SETCUEBANNER mesajını düzenleme kontrolüne göndermektir. yani.
[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);
}
Ayrıca, bir WinForm kontrol yaklaşımına ev sahipliği yapmak istiyorsanız, buradan ücretsiz olarak indirebileceğiniz BitFlex Framework adlı bu uygulamayı zaten içeren bir çerçevem var .
Daha fazla bilgi istiyorsanız BitFlex hakkında bir makale . Windows Gezgini tarzı kontrollere sahip olmak istiyorsanız, bunun genellikle kutudan çıkmadığını ve WPF'nin genellikle tutamaçlarla çalışmadığını görmeye başlayacaksınız ve Win32 veya sizin gibi mevcut bir kontrol etrafında kolay bir sarmalayıcı yazamayacaksınız. WinForms ile.
Ekran görüntüsü:
