Maison >développement back-end >C++ >Comment mettre en œuvre des filigranes de disparition dans les zones de texte WPF?

Comment mettre en œuvre des filigranes de disparition dans les zones de texte WPF?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2025-01-29 22:56:12963parcourir

How to Implement Disappearing Watermarks in WPF TextBoxes?

Watermark dans les zones de texte

Il est possible d'inclure du texte dans une zone de texte qui disparaît automatiquement lorsque l'utilisateur commence à taper.

Solution de propriété attachée

Cette solution utilise une propriété attachée pour ajouter des fonctionnalités de filigrane à n'importe quelle zone de texte:

WatermarkService.cs

using System;
using System.Windows;
using System.Windows.Controls;

public static class WatermarkService
{
    public static DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached(
        "Watermark",
        typeof(object),
        typeof(WatermarkService),
        new FrameworkPropertyMetadata((object)null, OnWatermarkChanged)
    );

    public static object GetWatermark(DependencyObject d)
    {
        return (object)d.GetValue(WatermarkProperty);
    }

    public static void SetWatermark(DependencyObject d, object value)
    {
        d.SetValue(WatermarkProperty, value);
    }

    private static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Control control = (Control)d;
        control.Loaded += Control_Loaded;

        if (d is TextBox)
        {
            control.GotKeyboardFocus += Control_GotKeyboardFocus;
            control.LostKeyboardFocus += Control_Loaded;
            ((TextBox)control).TextChanged += Control_GotKeyboardFocus;
        }
    }

    private static void Control_GotKeyboardFocus(object sender, RoutedEventArgs e)
    {
        Control c = (Control)sender;
        if (ShouldShowWatermark(c))
        {
            ShowWatermark(c);
        }
        else
        {
            RemoveWatermark(c);
        }
    }

    private static void Control_Loaded(object sender, RoutedEventArgs e)
    {
        Control control = (Control)sender;
        if (ShouldShowWatermark(control))
        {
            ShowWatermark(control);
        }
    }

    private static void RemoveWatermark(UIElement control)
    {
        AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);

        if (layer != null)
        {
            Adorner[] adorners = layer.GetAdorners(control);
            if (adorners == null)
            {
                return;
            }

            foreach (Adorner adorner in adorners)
            {
                if (adorner is WatermarkAdorner)
                {
                    adorner.Visibility = Visibility.Hidden;
                    layer.Remove(adorner);
                }
            }
        }
    }

    private static void ShowWatermark(Control control)
    {
        AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);

        if (layer != null)
        {
            layer.Add(new WatermarkAdorner(control, GetWatermark(control)));
        }
    }

    private static bool ShouldShowWatermark(Control c)
    {
        if (c is TextBox)
        {
            return (c as TextBox).Text == string.Empty;
        }
        else
        {
            return false;
        }
    }
}

watermarkadorner.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;

internal class WatermarkAdorner : Adorner
{
    private ContentPresenter contentPresenter;

    public WatermarkAdorner(UIElement adornedElement, object watermark) :
       base(adornedElement)
    {
        this.IsHitTestVisible = false;

        this.contentPresenter = new ContentPresenter();
        this.contentPresenter.Content = watermark;
        this.contentPresenter.Opacity = 0.5;
        this.contentPresenter.Margin = new Thickness(Control.Margin.Left + Control.Padding.Left, Control.Margin.Top + Control.Padding.Top, 0, 0);

        // Hide the control adorner when the adorned element is hidden
        Binding binding = new Binding("IsVisible");
        binding.Source = adornedElement;
        binding.Converter = new BooleanToVisibilityConverter();
        this.SetBinding(VisibilityProperty, binding);
    }

    protected override int VisualChildrenCount
    {
        get { return 1; }
    }

    private Control Control
    {
        get { return (Control)this.AdornedElement; }
    }

    protected override Visual GetVisualChild(int index)
    {
        return this.contentPresenter;
    }

    protected override Size MeasureOverride(Size constraint)
    {
        this.contentPresenter.Measure(Control.RenderSize);
        return Control.RenderSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        this.contentPresenter.Arrange(new Rect(finalSize));
        return finalSize;
    }
}

Maintenant, ajoutez un filigrane à n'importe quelle zone de texte en utilisant ce code:

<AdornerDecorator>
    <TextBox x:Name="SearchTextBox">
        <controls:WatermarkService.Watermark>
            <TextBlock>Type here to search text</TextBlock>
        </controls:WatermarkService.Watermark>
    </TextBox>
</AdornerDecorator>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn