জলছবি / ইঙ্গিত পাঠ্য / স্থানধারক পাঠ্যবক্স


264

আমি কোনও পাঠ্যকে কীভাবে কোনও পাঠ্যবক্সে রাখতে পারি যা ব্যবহারকারী এতে কিছু টাইপ করলে স্বয়ংক্রিয়ভাবে মুছে ফেলা হয়?


48
এটি এইচটিএমএলে একটি 'স্থানধারক' বলা হয়। লোকেরা এই পৃষ্ঠাটি গুগল করতে সহায়তা করার জন্য আমি এটি উল্লেখ করেছি।
স্কট স্টাফোর্ড

3
আপনি যদি উইন্ডোজ 10 এ ইউডাব্লুপি অ্যাপ্লিকেশন লিখছেন তবে এটি অনেক সহজ। <টেক্সটবক্স প্লেসহোল্ডারেক্সট = "অনুসন্ধান" /> আরও তথ্য: এমএসডিএন.মাইক্রোসফটকম
ব্ল্যাক মর্ন

উত্তর:


57

এটি এমন একটি নমুনা যা ডাব্লুপিএফ-তে একটি জলছবি পাঠ্যবাক্স কীভাবে তৈরি করবেন তা দেখায়:

<Window x:Class="WaterMarkTextBoxDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WaterMarkTextBoxDemo"
    Height="200" Width="400">

    <Window.Resources>

        <SolidColorBrush x:Key="brushWatermarkBackground" Color="White" />
        <SolidColorBrush x:Key="brushWatermarkForeground" Color="LightSteelBlue" />
        <SolidColorBrush x:Key="brushWatermarkBorder" Color="Indigo" />

        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        <local:TextInputToVisibilityConverter x:Key="TextInputToVisibilityConverter" />

        <Style x:Key="EntryFieldStyle" TargetType="Grid" >
            <Setter Property="HorizontalAlignment" Value="Stretch" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="Margin" Value="20,0" />
        </Style>

    </Window.Resources>


    <Grid Background="LightBlue">

        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Grid Grid.Row="0" Background="{StaticResource brushWatermarkBackground}" Style="{StaticResource EntryFieldStyle}" >
            <TextBlock Margin="5,2" Text="This prompt dissappears as you type..." Foreground="{StaticResource brushWatermarkForeground}"
                       Visibility="{Binding ElementName=txtUserEntry, Path=Text.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}}" />
            <TextBox Name="txtUserEntry" Background="Transparent" BorderBrush="{StaticResource brushWatermarkBorder}" />
        </Grid>

        <Grid Grid.Row="1" Background="{StaticResource brushWatermarkBackground}" Style="{StaticResource EntryFieldStyle}" >
            <TextBlock Margin="5,2" Text="This dissappears as the control gets focus..." Foreground="{StaticResource brushWatermarkForeground}" >
                <TextBlock.Visibility>
                    <MultiBinding Converter="{StaticResource TextInputToVisibilityConverter}">
                        <Binding ElementName="txtUserEntry2" Path="Text.IsEmpty" />
                        <Binding ElementName="txtUserEntry2" Path="IsFocused" />
                    </MultiBinding>
                </TextBlock.Visibility>
            </TextBlock>
            <TextBox Name="txtUserEntry2" Background="Transparent" BorderBrush="{StaticResource brushWatermarkBorder}" />
        </Grid>

    </Grid>

</Window>

পাঠ্য ইনপুটটোভিজিবিলিটি কনভার্টারটি হিসাবে সংজ্ঞায়িত করা হয়:

using System;
using System.Windows.Data;
using System.Windows;

namespace WaterMarkTextBoxDemo
{
    public class TextInputToVisibilityConverter : IMultiValueConverter
    {
        public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture )
        {
            // Always test MultiValueConverter inputs for non-null
            // (to avoid crash bugs for views in the designer)
            if (values[0] is bool && values[1] is bool)
            {
                bool hasText = !(bool)values[0];
                bool hasFocus = (bool)values[1];

                if (hasFocus || hasText)
                    return Visibility.Collapsed;
            }

            return Visibility.Visible;
        }


        public object[] ConvertBack( object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture )
        {
            throw new NotImplementedException();
        }
    }
}

দ্রষ্টব্য: এটি আমার কোড নয়। আমি এটি এখানে খুঁজে পেয়েছি , তবে আমি মনে করি এটি সর্বোত্তম পন্থা।


5
আমি কীভাবে এটি একটি পাসওয়ার্ডবক্সে প্রয়োগ করতে পারি?
সুরন

91
সেরা পন্থা? অবশ্যই না! আপনি যখন বার বার ওয়াটারমার্কের প্রয়োজন তখন আপনি কি সত্যিই অনেকগুলি কোডের টাইপ করতে চান? সংযুক্ত সম্পত্তির সাথে সমাধানটি পুনঃব্যবহার করা অনেক সহজ ...
টমাস লেভেস্ক

5
একটি ইউজারকন্ট্রোল তৈরির কথা বিবেচনা করুন।
সিএসহার্পার

6
যদিও সম্প্রদায়কে সহায়তা করার জন্য আপনার প্রয়াসের আমি সত্যই প্রশংসা করি, তবে সত্যিই বলতে হবে এটি একটি শালীন দৃষ্টিভঙ্গি থেকেও দূরে।
r41n

2
এই কোডটি অ্যান্ডি এল দ্বারা তৈরি করা হয়েছিল আপনি কোডেপ্রজেক্টে এটি খুঁজে পেতে পারেন ।
এওলসডিজ কোডিড্যাকট.কম

440

আপনি এমন একটি জলছবি তৈরি করতে পারেন যা TextBoxসংযুক্ত সম্পত্তি সহ যে কোনওটিতে যুক্ত করা যায় । সংযুক্ত সম্পত্তির উত্স এখানে:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;

/// <summary>
/// Class that provides the Watermark attached property
/// </summary>
public static class WatermarkService
{
    /// <summary>
    /// Watermark Attached Dependency Property
    /// </summary>
    public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached(
       "Watermark",
       typeof(object),
       typeof(WatermarkService),
       new FrameworkPropertyMetadata((object)null, new PropertyChangedCallback(OnWatermarkChanged)));

    #region Private Fields

    /// <summary>
    /// Dictionary of ItemsControls
    /// </summary>
    private static readonly Dictionary<object, ItemsControl> itemsControls = new Dictionary<object, ItemsControl>();

    #endregion

    /// <summary>
    /// Gets the Watermark property.  This dependency property indicates the watermark for the control.
    /// </summary>
    /// <param name="d"><see cref="DependencyObject"/> to get the property from</param>
    /// <returns>The value of the Watermark property</returns>
    public static object GetWatermark(DependencyObject d)
    {
        return (object)d.GetValue(WatermarkProperty);
    }

    /// <summary>
    /// Sets the Watermark property.  This dependency property indicates the watermark for the control.
    /// </summary>
    /// <param name="d"><see cref="DependencyObject"/> to set the property on</param>
    /// <param name="value">value of the property</param>
    public static void SetWatermark(DependencyObject d, object value)
    {
        d.SetValue(WatermarkProperty, value);
    }

    /// <summary>
    /// Handles changes to the Watermark property.
    /// </summary>
    /// <param name="d"><see cref="DependencyObject"/> that fired the event</param>
    /// <param name="e">A <see cref="DependencyPropertyChangedEventArgs"/> that contains the event data.</param>
    private static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Control control = (Control)d;
        control.Loaded += Control_Loaded;

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

        if (d is ItemsControl && !(d is ComboBox))
        {
            ItemsControl i = (ItemsControl)d;

            // for Items property  
            i.ItemContainerGenerator.ItemsChanged += ItemsChanged;
            itemsControls.Add(i.ItemContainerGenerator, i);

            // for ItemsSource property  
            DependencyPropertyDescriptor prop = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, i.GetType());
            prop.AddValueChanged(i, ItemsSourceChanged);
        }
    }

    #region Event Handlers

    /// <summary>
    /// Handle the GotFocus event on the control
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="RoutedEventArgs"/> that contains the event data.</param>
    private static void Control_GotKeyboardFocus(object sender, RoutedEventArgs e)
    {
        Control c = (Control)sender;
        if (ShouldShowWatermark(c))
        {
            ShowWatermark(c);
        }
        else
        {
            RemoveWatermark(c);
        }
    }

    /// <summary>
    /// Handle the Loaded and LostFocus event on the control
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="RoutedEventArgs"/> that contains the event data.</param>
    private static void Control_Loaded(object sender, RoutedEventArgs e)
    {
        Control control = (Control)sender;
        if (ShouldShowWatermark(control))
        {
            ShowWatermark(control);
        }
    }

    /// <summary>
    /// Event handler for the items source changed event
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="EventArgs"/> that contains the event data.</param>
    private static void ItemsSourceChanged(object sender, EventArgs e)
    {
        ItemsControl c = (ItemsControl)sender;
        if (c.ItemsSource != null)
        {
            if (ShouldShowWatermark(c))
            {
                ShowWatermark(c);
            }
            else
            {
                RemoveWatermark(c);
            }
        }
        else
        {
            ShowWatermark(c);
        }
    }

    /// <summary>
    /// Event handler for the items changed event
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="ItemsChangedEventArgs"/> that contains the event data.</param>
    private static void ItemsChanged(object sender, ItemsChangedEventArgs e)
    {
        ItemsControl control;
        if (itemsControls.TryGetValue(sender, out control))
        {
            if (ShouldShowWatermark(control))
            {
                ShowWatermark(control);
            }
            else
            {
                RemoveWatermark(control);
            }
        }
    }

    #endregion

    #region Helper Methods

    /// <summary>
    /// Remove the watermark from the specified element
    /// </summary>
    /// <param name="control">Element to remove the watermark from</param>
    private static void RemoveWatermark(UIElement control)
    {
        AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);

        // layer could be null if control is no longer in the visual tree
        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);
                }
            }
        }
    }

    /// <summary>
    /// Show the watermark on the specified control
    /// </summary>
    /// <param name="control">Control to show the watermark on</param>
    private static void ShowWatermark(Control control)
    {
        AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);

        // layer could be null if control is no longer in the visual tree
        if (layer != null)
        {
            layer.Add(new WatermarkAdorner(control, GetWatermark(control)));
        }
    }

    /// <summary>
    /// Indicates whether or not the watermark should be shown on the specified control
    /// </summary>
    /// <param name="c"><see cref="Control"/> to test</param>
    /// <returns>true if the watermark should be shown; false otherwise</returns>
    private static bool ShouldShowWatermark(Control c)
    {
        if (c is ComboBox)
        {
            return (c as ComboBox).Text == string.Empty;
        }
        else if (c is TextBoxBase)
        {
            return (c as TextBox).Text == string.Empty;
        }
        else if (c is ItemsControl)
        {
            return (c as ItemsControl).Items.Count == 0;
        }
        else
        {
            return false;
        }
    }

    #endregion
}

সংযুক্ত সম্পত্তি একটি ক্লাস ব্যবহার করে WatermarkAdorner, এটি উত্সটি এখানে:

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

/// <summary>
/// Adorner for the watermark
/// </summary>
internal class WatermarkAdorner : Adorner
{
    #region Private Fields

    /// <summary>
    /// <see cref="ContentPresenter"/> that holds the watermark
    /// </summary>
    private readonly ContentPresenter contentPresenter;

    #endregion

    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="WatermarkAdorner"/> class
    /// </summary>
    /// <param name="adornedElement"><see cref="UIElement"/> to be adorned</param>
    /// <param name="watermark">The watermark</param>
    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);

        if (this.Control is ItemsControl && !(this.Control is ComboBox))
        {
            this.contentPresenter.VerticalAlignment = VerticalAlignment.Center;
            this.contentPresenter.HorizontalAlignment = HorizontalAlignment.Center;
        }

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

    #endregion

    #region Protected Properties

    /// <summary>
    /// Gets the number of children for the <see cref="ContainerVisual"/>.
    /// </summary>
    protected override int VisualChildrenCount
    {
        get { return 1; }
    }

    #endregion

    #region Private Properties

    /// <summary>
    /// Gets the control that is being adorned
    /// </summary>
    private Control Control
    {
        get { return (Control)this.AdornedElement; }
    }

    #endregion

    #region Protected Overrides

    /// <summary>
    /// Returns a specified child <see cref="Visual"/> for the parent <see cref="ContainerVisual"/>.
    /// </summary>
    /// <param name="index">A 32-bit signed integer that represents the index value of the child <see cref="Visual"/>. The value of index must be between 0 and <see cref="VisualChildrenCount"/> - 1.</param>
    /// <returns>The child <see cref="Visual"/>.</returns>
    protected override Visual GetVisualChild(int index)
    {
        return this.contentPresenter;
    }

    /// <summary>
    /// Implements any custom measuring behavior for the adorner.
    /// </summary>
    /// <param name="constraint">A size to constrain the adorner to.</param>
    /// <returns>A <see cref="Size"/> object representing the amount of layout space needed by the adorner.</returns>
    protected override Size MeasureOverride(Size constraint)
    {
        // Here's the secret to getting the adorner to cover the whole control
        this.contentPresenter.Measure(Control.RenderSize);
        return Control.RenderSize;
    }

    /// <summary>
    /// When overridden in a derived class, positions child elements and determines a size for a <see cref="FrameworkElement"/> derived class. 
    /// </summary>
    /// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param>
    /// <returns>The actual size used.</returns>
    protected override Size ArrangeOverride(Size finalSize)
    {
        this.contentPresenter.Arrange(new Rect(finalSize));
        return finalSize;
    }

    #endregion
}

এখন আপনি এই জাতীয় কোনও পাঠ্যবক্সে একটি জলছবি রাখতে পারেন:

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

জলছাপ আপনার পছন্দসই কিছু হতে পারে (পাঠ্য, চিত্র ...)। টেক্সটবক্সে কাজ করার পাশাপাশি, এই ওয়াটারমার্কটি কম্বোবক্স এবং আইটেমকন্ট্রোলগুলির জন্যও কাজ করে।

এই কোডটি এই ব্লগ পোস্ট থেকে অভিযোজিত হয়েছিল ।


11
আমি এটিকে ওয়াটারমার্কএডোনার কন্সট্রাক্টর মার্জিন অ্যাসাইনমেন্টটি সংশোধন করে সমাধান করেছি: মার্জিন = নতুন পুরুত্ব (
কন্ট্রোল.প্যাডিং। লেফট, কন্ট্রোল.প্যাডিং.টপ

3
@ জনমাইকাজিক ওয়াটারমার্ককে স্থানীয়করণের জন্য: কীভাবে আমি ভিউমোডেলের কোনও সম্পত্তিতে ওয়াটারমার্ক এক্সামল ঘোষণায় টেক্সটবক্সকে পাঠাতে পারি?
জোয়ানকোমাসএফডিজেড

7
@ ম্যাটজে @ জোয়ানকোমাসএফডিজেড এখানে আমি কীভাবে TextBlock.Textআমার ভিউ মডেলটির সাথে সম্পত্তিটি আবদ্ধ করতে পারি (এটি WatermarkAdornerকনস্ট্রাক্টারে রাখুন): FrameworkElement feWatermark = watermark as FrameworkElement; if(feWatermark != null && feWatermark.DataContext == null) { feWatermark.DataContext = this.Control.DataContext; }
শান হল

9
সম্ভাব্য মেমরি লিঙ্ক এখানে। আপনি অভ্যন্তরীণ স্থিতিশীল অভিধানে ওয়াটারমার্ক করা নিয়ন্ত্রণগুলি যুক্ত করছেন তবে সেগুলি কখনই সরাবেন না। আপনার মতামতগুলি একবার সম্পন্ন করার পরে এটি আবর্জনা সংগ্রহ করা থেকে সম্ভবত প্রতিরোধ করবে। আমি এখানে একটি দুর্বল রেফারেন্স ব্যবহার করে বিবেচনা করব।
জ্যারেড জি

3
আইটেমকন্ট্রোলগুলির স্থির অভিধানের পাশাপাশি, সম্পত্তি বিবরণীর কোড মেমরি ফাঁস করে। আপনাকে রিমুভ্যালু চেঞ্জড () কল করতে হবে। সুতরাং আপনি এই কোডটি ব্যবহার করার সময় সাবধান হন।
মুকু

284

কেবল এক্সএএমএল ব্যবহার করছে, কোনও এক্সটেনশান নেই, কোনও রূপান্তরকারী নেই:

<Grid>
    <TextBox  Width="250"  VerticalAlignment="Center" HorizontalAlignment="Left" x:Name="SearchTermTextBox" Margin="5"/>
    <TextBlock IsHitTestVisible="False" Text="Enter Search Term Here" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0" Foreground="DarkGray">
        <TextBlock.Style>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="Visibility" Value="Collapsed"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Text, ElementName=SearchTermTextBox}" Value="">
                        <Setter Property="Visibility" Value="Visible"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</Grid>

3
অত্যন্ত সাধারণ এক, সেরা ইমোও। আমি জানি না আপনি যখন এই সমস্ত 10 টি এক্সএএমএল স্ক্রিপ্টটি পেতে পারেন তখন আপনি কেন এই সমস্তগুলি ব্যবহার করবেন। ধন্যবাদ।
dj.lnxss

4
আপনি একটি যোগ করতে চান করতে পারেন Padding="6,3,0,0"থেকে TextBlock
কোডিড্যাক্ট ডট কম এলোয়েসডাগ

1
খুব সুন্দর, তবে এটি উইন্ডোজ ফোন সিলভারলাইটে কাজ করে না :-(
আন্দ্রে আন্টোনঙ্গেলি

14
কীভাবে কেউ এটি পুনরায় ব্যবহারযোগ্য নিয়ন্ত্রণ টেম্পলেট তৈরি করতে পারেন?
রিচার্ড 21

2
@ সাইরিয়ানক্স এটি কারণ যে কোনও পাসওয়ার্ডবক্সে পাসওয়ার্ড সম্পত্তি সুরক্ষার কারণে বাধ্যযোগ্য নয়। আপনি এখানে উদাহরণটি ব্যবহার করে এটি বাইন্ডেবল করতে পারেন: wpftutorial.net/PasswordBox.html তবে এই ক্ষেত্রে দৃশ্যমানতাটি সেট করার জন্য পাসওয়ার্ড চেঞ্জড ইভেন্ট এবং পেছনের কোডটি ব্যবহার করা সম্ভবত দ্রুত এবং সহজ।
এপিসি

54

আমি বিশ্বাস করতে পারি না যে এক্সসিডের কাছ থেকে স্পষ্ট বর্ধিত ডাব্লুপিএফ টুলকিট - ওয়াটারমার্কটেক্সটবক্স কেউ পোস্ট করেনি । এটি বেশ ভাল কাজ করে এবং আপনি কাস্টমাইজ করতে চান ক্ষেত্রে এটি ওপেন সোর্স।


5
আমার উইন 8 মেশিনে সমস্ত ডাব্লুপিএফ টুলকিট নিয়ন্ত্রণগুলিতে উইন্ডোজ 7 স্টাইল (বৃত্তাকার কোণার, ইত্যাদি) থাকে। এবং মানক নিয়ন্ত্রণের সাথে মিশ্রিত হওয়ার পরে যে কোনও ডাব্লুপিএফ টুলকিট নিয়ন্ত্রণ সম্পূর্ণ জায়গা থেকে বাইরে দেখায়।
Gman

1
জন মাইকিজের "সংযুক্ত সম্পত্তি" পদ্ধতির একটি বাগ রয়েছে যার মাধ্যমে যদি পাঠ্যবক্সটি অন্য কোনও উপাদান দ্বারা আচ্ছাদিত করা হয় তবে ওয়াটারমার্কটি রক্তপাত করবে এবং এখনও দৃশ্যমান হবে। এই সমাধানটিতে এই সমস্যা নেই। (যদি আমি ইতিমধ্যে যেকোনোভাবেই টুলকিটটি ব্যবহার করছি তবে আমি এটি আগে লক্ষ্য করেছি। আরও upvotes প্রাপ্য।
ডেক্স ফোহল

জন মাইকিজকের সমাধানটিতে একটি আপাত মেমরি ফুটো রয়েছে, যেখানে ওয়াটারমার্ক সার্ভিসেস কোনও আইটেমকন্ট্রোলের সাথে স্থির অভিধানে একটি রেফারেন্স রাখবে যার সাথে জলছবি সংযুক্ত হয়ে যায়। এটি অবশ্যই স্থির করা যেতে পারে তবে আমি এক্সটেন্ডেড ডাব্লুপিএফ টুলকিট সংস্করণটি দিয়ে চেষ্টা করব।
এমবারজিয়েল

34

"এক্সএএমএল এর 3 লাইনে" কীভাবে এটি করা যায় সে সম্পর্কে কোডপ্রজেক্টে একটি নিবন্ধ রয়েছে

<Grid Background="{StaticResource brushWatermarkBackground}">
  <TextBlock Margin="5,2" Text="Type something..."
             Foreground="{StaticResource brushForeground}"
             Visibility="{Binding ElementName=txtUserEntry, Path=Text.IsEmpty,
                          Converter={StaticResource BooleanToVisibilityConverter}}" />
  <TextBox Name="txtUserEntry" Background="Transparent"
           BorderBrush="{StaticResource brushBorder}" />
</Grid>

ঠিক আছে, ভাল এটি XAML ফরম্যাট 3 লাইন নাও হতে পারে, কিন্তু এটা হয় বেশ সহজ।

তবে একটি বিষয় লক্ষণীয়, এটি পাঠ্যের সম্পত্তিতে একটি "মানহীন প্রসারিত পদ্ধতি" ব্যবহার করে, এটি "ইসেম্পটি" নামে পরিচিত। আপনার নিজের এটি প্রয়োগ করতে হবে, তবে নিবন্ধটি উল্লেখ করার মতো বলে মনে হচ্ছে না।


9
পাঠ্যবক্সে থাকা উচিত IsHitTestVisible="False"। এছাড়াও, এটি পাঠ্যবক্সের পরে আসা উচিত, অন্যথায় পাঠ্যবক্সের ব্যাকগ্রাউন্ড থাকলে এটি দৃশ্যমান নাও হতে পারে।
এনিভেস

কোডপ্রজেক্টের সেই নিবন্ধটি কেবল খারাপ।
Xam

2
কীভাবে Text.IsEmptyকাজ করে: সংগ্রহ
ভিউ.আইএসইপটি

19

আমি দেখেছি জন Myczek এর সমাধান , এবং উপযুক্ততা সম্পর্কে এর মন্তব্য ComboBoxএবং PasswordBoxতাই আমি জন Myczek এর সমাধান উন্নত, এবং এটি হল:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;

/// <summary>
/// Class that provides the Watermark attached property
/// </summary>
public static class WatermarkService
{
    /// <summary>
    /// Watermark Attached Dependency Property
    /// </summary>
    public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached(
       "Watermark",
       typeof(object),
       typeof(WatermarkService),
       new FrameworkPropertyMetadata((object)null, new PropertyChangedCallback(OnWatermarkChanged)));

    #region Private Fields

    /// <summary>
    /// Dictionary of ItemsControls
    /// </summary>
    private static readonly Dictionary<object, ItemsControl> itemsControls = new Dictionary<object, ItemsControl>();

    #endregion

    /// <summary>
    /// Gets the Watermark property.  This dependency property indicates the watermark for the control.
    /// </summary>
    /// <param name="d"><see cref="DependencyObject"/> to get the property from</param>
    /// <returns>The value of the Watermark property</returns>
    public static object GetWatermark(DependencyObject d)
    {
        return (object)d.GetValue(WatermarkProperty);
    }

    /// <summary>
    /// Sets the Watermark property.  This dependency property indicates the watermark for the control.
    /// </summary>
    /// <param name="d"><see cref="DependencyObject"/> to set the property on</param>
    /// <param name="value">value of the property</param>
    public static void SetWatermark(DependencyObject d, object value)
    {
        d.SetValue(WatermarkProperty, value);
    }

    /// <summary>
    /// Handles changes to the Watermark property.
    /// </summary>
    /// <param name="d"><see cref="DependencyObject"/> that fired the event</param>
    /// <param name="e">A <see cref="DependencyPropertyChangedEventArgs"/> that contains the event data.</param>
    private static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Control control = (Control)d;
        control.Loaded += Control_Loaded;

        if (d is TextBox || d is PasswordBox)
        {
            control.GotKeyboardFocus += Control_GotKeyboardFocus;
            control.LostKeyboardFocus += Control_Loaded;
        }
        else if (d is ComboBox)
        {
            control.GotKeyboardFocus += Control_GotKeyboardFocus;
            control.LostKeyboardFocus += Control_Loaded;
            (d as ComboBox).SelectionChanged += new SelectionChangedEventHandler(SelectionChanged);
        }
        else if (d is ItemsControl)
        {
            ItemsControl i = (ItemsControl)d;

            // for Items property  
            i.ItemContainerGenerator.ItemsChanged += ItemsChanged;
            itemsControls.Add(i.ItemContainerGenerator, i);

            // for ItemsSource property  
            DependencyPropertyDescriptor prop = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, i.GetType());
            prop.AddValueChanged(i, ItemsSourceChanged);
        }
    }

    /// <summary>
    /// Event handler for the selection changed event
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="ItemsChangedEventArgs"/> that contains the event data.</param>
    private static void SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        Control control = (Control)sender;
        if (ShouldShowWatermark(control))
        {
            ShowWatermark(control);
        }
        else
        {
            RemoveWatermark(control);
        }
    }

    #region Event Handlers

    /// <summary>
    /// Handle the GotFocus event on the control
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="RoutedEventArgs"/> that contains the event data.</param>
    private static void Control_GotKeyboardFocus(object sender, RoutedEventArgs e)
    {
        Control c = (Control)sender;
        if (ShouldShowWatermark(c))
        {
            RemoveWatermark(c);
        }
    }

    /// <summary>
    /// Handle the Loaded and LostFocus event on the control
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="RoutedEventArgs"/> that contains the event data.</param>
    private static void Control_Loaded(object sender, RoutedEventArgs e)
    {
        Control control = (Control)sender;
        if (ShouldShowWatermark(control))
        {
            ShowWatermark(control);
        }
    }

    /// <summary>
    /// Event handler for the items source changed event
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="EventArgs"/> that contains the event data.</param>
    private static void ItemsSourceChanged(object sender, EventArgs e)
    {
        ItemsControl c = (ItemsControl)sender;
        if (c.ItemsSource != null)
        {
            if (ShouldShowWatermark(c))
            {
                ShowWatermark(c);
            }
            else
            {
                RemoveWatermark(c);
            }
        }
        else
        {
            ShowWatermark(c);
        }
    }

    /// <summary>
    /// Event handler for the items changed event
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="ItemsChangedEventArgs"/> that contains the event data.</param>
    private static void ItemsChanged(object sender, ItemsChangedEventArgs e)
    {
        ItemsControl control;
        if (itemsControls.TryGetValue(sender, out control))
        {
            if (ShouldShowWatermark(control))
            {
                ShowWatermark(control);
            }
            else
            {
                RemoveWatermark(control);
            }
        }
    }

    #endregion

    #region Helper Methods

    /// <summary>
    /// Remove the watermark from the specified element
    /// </summary>
    /// <param name="control">Element to remove the watermark from</param>
    private static void RemoveWatermark(UIElement control)
    {
        AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);

        // layer could be null if control is no longer in the visual tree
        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);
                }
            }
        }
    }

    /// <summary>
    /// Show the watermark on the specified control
    /// </summary>
    /// <param name="control">Control to show the watermark on</param>
    private static void ShowWatermark(Control control)
    {
        AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);

        // layer could be null if control is no longer in the visual tree
        if (layer != null)
        {
            layer.Add(new WatermarkAdorner(control, GetWatermark(control)));
        }
    }

    /// <summary>
    /// Indicates whether or not the watermark should be shown on the specified control
    /// </summary>
    /// <param name="c"><see cref="Control"/> to test</param>
    /// <returns>true if the watermark should be shown; false otherwise</returns>
    private static bool ShouldShowWatermark(Control c)
    {
        if (c is ComboBox)
        {
            return (c as ComboBox).SelectedItem == null;
            //return (c as ComboBox).Text == string.Empty;
        }
        else if (c is TextBoxBase)
        {
            return (c as TextBox).Text == string.Empty;
        }
        else if (c is PasswordBox)
        {
            return (c as PasswordBox).Password == string.Empty;
        }
        else if (c is ItemsControl)
        {
            return (c as ItemsControl).Items.Count == 0;
        }
        else
        {
            return false;
        }
    }

    #endregion
}

এখন, এক ComboBoxএও হতে পারে Editable, এবং PasswordBoxএকটি জলছাপ খুব যোগ করতে পারেন। মার্জিন সমস্যা সমাধানের জন্য উপরের জোয়ানকোমাসফিডজ-এর মন্তব্যটি ব্যবহার করতে ভুলবেন না।

এবং, অবশ্যই, সমস্ত কৃতিত্ব জন মাইজেকের কাছে যায়।


4
এটি আসলে জন-মাইজেক কোডের সুন্দর টুকরাটির একটি উন্নত সংস্করণ এবং এটি কম্বো বাক্সের জন্য জরিমানা কাজ করেছে। দুজন কেই ধন্যবাদ!
সমুরিম

12

স্টাইল ব্যবহার করে সাধারণ সমাধান:

<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="MM:SS:HH AM/PM" 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>

দুর্দান্ত সমাধান:

https://code.msdn.microsoft.com/windowsdesktop/In-place-hit-messages-for-18db3a6c


1
এটি আমার
ফেভ


9

আমি সিপল কোড-শুধুমাত্র বাস্তবায়ন তৈরি করেছি যা ডাব্লুপিএফ এবং সিলভারলাইটের জন্যও দুর্দান্ত কাজ করে:

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

public class TextBoxWatermarked : TextBox
{
    #region [ Dependency Properties ]

    public static DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark",
                                                                             typeof(string),
                                                                             typeof(TextBoxWatermarked),
                                                                             new PropertyMetadata(new PropertyChangedCallback(OnWatermarkChanged)));


    #endregion


    #region [ Fields ]

    private bool _isWatermarked;
    private Binding _textBinding;

    #endregion


    #region [ Properties ]

    protected new Brush Foreground
    {
        get { return base.Foreground; }
        set { base.Foreground = value; }
    }

    public string Watermark
    {
        get { return (string)GetValue(WatermarkProperty); }
        set { SetValue(WatermarkProperty, value); }
    }

    #endregion


    #region [ .ctor ]

    public TextBoxWatermarked()
    {
        Loaded += (s, ea) => ShowWatermark();
    }

    #endregion


    #region [ Event Handlers ]

    protected override void OnGotFocus(RoutedEventArgs e)
    {
        base.OnGotFocus(e);
        HideWatermark();
    }

    protected override void OnLostFocus(RoutedEventArgs e)
    {
        base.OnLostFocus(e);
        ShowWatermark();
    }

    private static void OnWatermarkChanged(DependencyObject sender, DependencyPropertyChangedEventArgs ea)
    {
        var tbw = sender as TextBoxWatermarked;
        if (tbw == null) return;
        tbw.ShowWatermark();
    }

    #endregion


    #region [ Methods ]

    private void ShowWatermark()
    {
        if (string.IsNullOrEmpty(base.Text))
        {
            _isWatermarked = true;
            base.Foreground = new SolidColorBrush(Colors.Gray);
            var bindingExpression = GetBindingExpression(TextProperty);
            _textBinding = bindingExpression == null ? null : bindingExpression.ParentBinding;
            if (bindingExpression != null)
                bindingExpression.UpdateSource();
            SetBinding(TextProperty, new Binding());
            base.Text = Watermark;
        }
    }

    private void HideWatermark()
    {
        if (_isWatermarked)
        {
            _isWatermarked = false;
            ClearValue(ForegroundProperty);
            base.Text = "";
            SetBinding(TextProperty, _textBinding ?? new Binding());
        }
    }

    #endregion
}

ব্যবহার:

<TextBoxWatermarked Watermark="Some text" />

দুর্দান্ত সমাধান। অগ্রভাগ সম্পত্তি ছায়া কেন? সেটবাইন্ডিং (টেক্সটপ্রপার্টি, নতুন বাইন্ডিং ()) অবৈধ অপারেশন এক্সপেকশন: দ্বি-মুখী বাইন্ডিংয়ের জন্য পথ বা এক্সপথ দরকার?
টিম মারফি

আমি অগ্রভাগের সম্পত্তিটি আড়াল করি কারণ টেক্সটবক্সওয়াটারমার্কযুক্ত এটি তার নিজস্ব উদ্দেশ্যে ব্যবহার করে। আমি জানি না কেন অবৈধ অপারেশন ধারণাটি নিক্ষেপ করা হয়, আপনি যদি ডাব্লুপিএফ ব্যবহার করেন (আমি এটি সিলভারলাইট দিয়ে ব্যবহার করেছি) নতুন বাঁধাইয়ের () পরিবর্তে আপনাকে নাল পাস করতে হবে।
ভিতালিয়া উলান্টিকভ

2
WPF- এ এই কোডটি ব্যবহার করতে, উভয় জায়গার BindingOperations.ClearBinding(this, TextProperty)পরিবর্তে ব্যবহার করুন SetBinding(TextProperty, new Binding())
সেবাস্তিয়ান ক্রিসমানস্কি

1
এটি আসলে Textওয়াটারমার্কে পরিবর্তিত হয়। আমার জন্য কাজ করবে না।
লবস্টারিজম

এটিতে नेमস্পেসের লাইন যুক্ত করতে, বা এই স্টাফটির কিছুটা পুরোপুরি যোগ্যতা অর্জনের জন্য দরকারী।
রিচার্ড জুন

6

বাউন্ড টেক্সটবক্স সহ @ জন-মাইকিজ কোডটি ব্যবহার করার সময় আমি কিছুটা অসুবিধায় পড়েছিলাম । এটি আপডেট হওয়ার সাথে সাথে পাঠ্যবক্স কোনও ফোকাস ইভেন্ট উত্থাপন না করে, নতুন পাঠ্যের নীচে ওয়াটারমার্ক দৃশ্যমান থাকবে। এটি ঠিক করার জন্য, আমি কেবল অন্য ইভেন্ট হ্যান্ডলারটি যুক্ত করেছি:

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

    if (d is TextBox)
        (d as TextBox).TextChanged += Control_TextChanged;
}


private static void Control_TextChanged(object sender, RoutedEventArgs e)
{
    var tb = (TextBox)sender;
    if (ShouldShowWatermark(tb))
    {
        ShowWatermark(tb);
    }
    else
    {
        RemoveWatermark(tb);
    }
}

1
আশা করি আমি নিজেই উত্তর দেওয়ার আগে এই উত্তরটি লক্ষ্য করে ফেলেছি।
লবস্টারিজম

5

@ ওয়েটন - আমি আপনার সমাধানটির সরলতা সত্যিই পছন্দ করি তবে আমার খ্যাতি আপনাকে এতটা ধাক্কা মারার মতো পর্যাপ্ত নয় isn't

@ টিম মারফি - "দ্বি-মুখী বাঁধাইয়ের জন্য প্রয়োজন পথ বা এক্সপাথ" ত্রুটিটি ছিল একটি সহজ সমাধান ... কিছু অন্যান্য সামান্য টুইটসহ আপডেটেড কোড (কেবলমাত্র ডাব্লুপিএফ পরীক্ষিত):

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

public class TextBoxWatermarked : TextBox
{
  public string Watermark
  {
    get { return (string)GetValue(WaterMarkProperty); }
    set { SetValue(WaterMarkProperty, value); }
  }
  public static readonly DependencyProperty WaterMarkProperty =
      DependencyProperty.Register("Watermark", typeof(string), typeof(TextBoxWatermarked), new PropertyMetadata(new PropertyChangedCallback(OnWatermarkChanged)));

  private bool _isWatermarked = false;
  private Binding _textBinding = null;

  public TextBoxWatermarked()
  {
    Loaded += (s, ea) => ShowWatermark();
  }

  protected override void OnGotFocus(RoutedEventArgs e)
  {
    base.OnGotFocus(e);
    HideWatermark();
  }

  protected override void OnLostFocus(RoutedEventArgs e)
  {
    base.OnLostFocus(e);
    ShowWatermark();
  }

  private static void OnWatermarkChanged(DependencyObject sender, DependencyPropertyChangedEventArgs ea)
  {
    var tbw = sender as TextBoxWatermarked;
    if (tbw == null || !tbw.IsLoaded) return; //needed to check IsLoaded so that we didn't dive into the ShowWatermark() routine before initial Bindings had been made
    tbw.ShowWatermark();
  }

  private void ShowWatermark()
  {
    if (String.IsNullOrEmpty(Text) && !String.IsNullOrEmpty(Watermark))
    {
      _isWatermarked = true;

      //save the existing binding so it can be restored
      _textBinding = BindingOperations.GetBinding(this, TextProperty);

      //blank out the existing binding so we can throw in our Watermark
      BindingOperations.ClearBinding(this, TextProperty);

      //set the signature watermark gray
      Foreground = new SolidColorBrush(Colors.Gray);

      //display our watermark text
      Text = Watermark;
    }
  }

  private void HideWatermark()
  {
    if (_isWatermarked)
    {
      _isWatermarked = false;
      ClearValue(ForegroundProperty);
      Text = "";
      if (_textBinding != null) SetBinding(TextProperty, _textBinding);
    }
  }

}

3

আপনি এটি করতে ইভেন্ট GetFocus()এবং LostFocus()ইভেন্টগুলি ব্যবহার করতে পারেন

এখানে উদাহরণ:

    private void txtData1_GetFocus(object sender, RoutedEventArgs e)
    {
        if (txtData1.Text == "TextBox1abc")
        {
            txtData1.Text = string.Empty;
        }
    }

    private void txtData1_LostFocus(object sender, RoutedEventArgs e)
    {
        if (txtData1.Text == string.Empty)
        {
            txtData1.Text = "TextBox1abc";
        }
    }

2

টেক্সটবক্সের ওয়াটারমার্কের সহজতম উপায়

 <Window.Resources>
    <Style x:Key="MyWaterMarkStyle" TargetType="{x:Type TextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Grid>
                        <Border Background="White" BorderBrush="#FF7D8683" BorderThickness="1"/>
                        <ScrollViewer x:Name="PART_ContentHost" Margin="5,0,0,0" VerticalAlignment="Center" />
                        <Label Margin="5,0,0,0" x:Name="WaterMarkLabel" Content="{TemplateBinding Tag}" VerticalAlignment="Center"
                           Visibility="Collapsed" Foreground="Gray" FontFamily="Arial"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Text" Value=""/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Visibility" TargetName="WaterMarkLabel" Value="Visible"/>
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Foreground" Value="DimGray"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

এবং পাঠ্যবক্স স্ট্যাটিক রিসোর্স শৈলী যুক্ত করুন

  <TextBox
                Style="{StaticResource MyWaterMarkStyle}"
                Tag="Search Category"
                Grid.Row="0"
                Text="{Binding CategorySearch,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                TextSearch.Text="Search Category"
                >

1
<Window.Resources>

    <Style x:Key="TextBoxUserStyle" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
      <Setter Property="Foreground" Value="Black"/>
      <Setter Property="HorizontalAlignment" Value="Center"/>
      <Setter Property="VerticalContentAlignment" Value="Center"/>
      <Setter Property="Width" Value="225"/>
      <Setter Property="Height" Value="25"/>
      <Setter Property="FontSize" Value="12"/>
      <Setter Property="Padding" Value="1"/>
      <Setter Property="Margin" Value="5"/>
      <Setter Property="AllowDrop" Value="true"/>
      <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type TextBox}">
            <Border x:Name="OuterBorder" BorderBrush="#5AFFFFFF" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
              <Border x:Name="InnerBorder" Background="#FFFFFFFF" BorderBrush="#33000000" BorderThickness="1,1,1,1" CornerRadius="3,3,3,3">
                <ScrollViewer SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" x:Name="PART_ContentHost"/>
              </Border>
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

    <Style x:Key="PasswordBoxVistaStyle" BasedOn="{x:Null}" TargetType="{x:Type PasswordBox}">
      <Setter Property="Foreground" Value="Black"/>
      <Setter Property="HorizontalAlignment" Value="Center"/>
      <Setter Property="VerticalContentAlignment" Value="Center"/>
      <Setter Property="Width" Value="225"/>
      <Setter Property="Height" Value="25"/>
      <Setter Property="FontSize" Value="12"/>
      <Setter Property="Padding" Value="1"/>
      <Setter Property="Margin" Value="5"/>
      <Setter Property="AllowDrop" Value="true"/>
      <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type PasswordBox}">
            <Border x:Name="OuterBorder" BorderBrush="#5AFFFFFF" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
              <Border x:Name="InnerBorder" Background="#FFFFFFFF" BorderBrush="#33000000" BorderThickness="1,1,1,1" CornerRadius="3,3,3,3">
                <Grid>
                  <Label x:Name="lblPwd" Content="Password" FontSize="11" VerticalAlignment="Center" Margin="2,0,0,0" FontFamily="Verdana" Foreground="#828385" Padding="0"/>
                  <ScrollViewer SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" x:Name="PART_ContentHost"/>
                </Grid>
              </Border>
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsFocused" Value="True">
                <Setter Property="Visibility" TargetName="lblPwd" Value="Hidden"/>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Window.Resources>


        <PasswordBox Style="{StaticResource PasswordBoxVistaStyle}" Margin="169,143,22,0" Name="txtPassword" FontSize="14" TabIndex="2" Height="31" VerticalAlignment="Top" />

এটি আপনার কোড দিয়ে এটি পরীক্ষা করতে সহায়তা করে password পাসওয়ার্ড বাক্সে প্রয়োগ করা হলে এটি পাসওয়ার্ড প্রদর্শন করবে, যা ব্যবহারকারীর টাইপগুলি অদৃশ্য হয়ে যাবে।


1

ভাল এখানে আমার: অগত্যা সেরা না, তবে এটি সহজ হিসাবে আপনার স্বাদে সম্পাদনা করা সহজ।

<UserControl x:Class="WPFControls.ShadowedTextBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPFControls"
    Name="Root">
<UserControl.Resources>
    <local:ShadowConverter x:Key="ShadowConvert"/>
</UserControl.Resources>
<Grid>
    <TextBox Name="textBox" 
             Foreground="{Binding ElementName=Root, Path=Foreground}"
             Text="{Binding ElementName=Root, Path=Text, UpdateSourceTrigger=PropertyChanged}"
             TextChanged="textBox_TextChanged"
             TextWrapping="Wrap"
             VerticalContentAlignment="Center"/>
    <TextBlock Name="WaterMarkLabel"
           IsHitTestVisible="False"
           Foreground="{Binding ElementName=Root,Path=Foreground}"
           FontWeight="Thin"
           Opacity=".345"
           FontStyle="Italic"
           Text="{Binding ElementName=Root, Path=Watermark}"
           VerticalAlignment="Center"
           TextWrapping="Wrap"
           TextAlignment="Center">
        <TextBlock.Visibility>
            <MultiBinding Converter="{StaticResource ShadowConvert}">
                <Binding ElementName="textBox" Path="Text"/>
            </MultiBinding>
        </TextBlock.Visibility> 
    </TextBlock>
</Grid>

রূপান্তরকারী, যেমন এটি এখন লিখিত হয়েছে এটি কোনও মাল্টি-কনভার্টার হিসাবে প্রয়োজন হয় না, তবে এই নোংরা মধ্যে এটি সহজেই প্রসারিত করা যেতে পারে

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace WPFControls
{
    class ShadowConverter:IMultiValueConverter
    {
        #region Implementation of IMultiValueConverter

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var text = (string) values[0];
            return text == string.Empty
                       ? Visibility.Visible
                       : Visibility.Collapsed;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            return new object[0];
        }

        #endregion
    }
}

এবং অবশেষে পিছনে কোড:

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

namespace WPFControls
{
    /// <summary>
    /// Interaction logic for ShadowedTextBox.xaml
    /// </summary>
    public partial class ShadowedTextBox : UserControl
    {
        public event TextChangedEventHandler TextChanged;

        public ShadowedTextBox()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty WatermarkProperty =
            DependencyProperty.Register("Watermark",
                                        typeof (string),
                                        typeof (ShadowedTextBox),
                                        new UIPropertyMetadata(string.Empty));

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text",
                                        typeof (string),
                                        typeof (ShadowedTextBox),
                                        new UIPropertyMetadata(string.Empty));

        public static readonly DependencyProperty TextChangedProperty =
            DependencyProperty.Register("TextChanged",
                                        typeof (TextChangedEventHandler),
                                        typeof (ShadowedTextBox),
                                        new UIPropertyMetadata(null));

        public string Watermark
        {
            get { return (string)GetValue(WatermarkProperty); }
            set
            {
                SetValue(WatermarkProperty, value);
            }
        }

        public string Text
        {
            get { return (string) GetValue(TextProperty); }
            set{SetValue(TextProperty,value);}
        }

        private void textBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (TextChanged != null) TextChanged(this, e);
        }

        public void Clear()
        {
            textBox.Clear();
        }

    }
}

1
<TextBox x:Name="OrderTxt" HorizontalAlignment="Left" VerticalAlignment="Top" VerticalContentAlignment="Center" Margin="10,10,0,0" Width="188" Height="32"/>

<Label IsHitTestVisible="False" Content="Order number" DataContext="{Binding ElementName=OrderTxt}" Foreground="DarkGray">
    <Label.Style>
        <Style TargetType="{x:Type Label}">
            <Setter Property="Visibility" Value="Collapsed"/>
            <Setter Property="Width" Value="{Binding Width}"/>
            <Setter Property="Height" Value="{Binding Height}"/>
            <Setter Property="Margin" Value="{Binding Margin}"/>
            <Setter Property="VerticalAlignment" Value="{Binding VerticalAlignment}"/>
            <Setter Property="HorizontalAlignment" Value="{Binding HorizontalAlignment}"/>
            <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Text}" Value="">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Label.Style>
</Label>

দয়া করে কিছু ব্যাখ্যা যুক্ত করুন
মোহিত জৈন

1

ডাব্লুপিএফ-এর জন্য মাহপ্পস.মেট্রোর একটি অন্তর্নির্মিত ওয়াটারমার্ক নিয়ন্ত্রণ রয়েছে, যদি আপনি বরং নিজেরটি রোল না করেন। এটি ব্যবহার করা মোটামুটি সোজা

 <AdornerDecorator>
            <TextBox Name="txtSomeText"
                     Width="200"
                     HorizontalAlignment="Right">
                <Controls:TextBoxHelper.Watermark>I'm a watermark!</Controls:TextBoxHelper.Watermark>
            </TextBox>
        </AdornerDecorator>

1

একটি নরম রঙে স্থানধারক পাঠ্য সহ পাঠ্য বাক্সটি সেট আপ করুন ...

public MainWindow ( )
{
    InitializeComponent ( );
    txtInput.Text = "Type something here...";
    txtInput.Foreground = Brushes.DimGray;
}

যখন পাঠ্য বাক্সটি ফোকাসটি পেয়েছে, এটি সাফ করুন এবং পাঠ্যের রঙ পরিবর্তন করুন

private void txtInput_GotFocus ( object sender, EventArgs e )
{
    MessageBox.Show ( "got focus" );
    txtInput.Text = "";
    txtInput.Foreground = Brushes.Red;
}

1

এখানে সহজ সমাধান:

            <Grid>
                <Label Content="Placeholder text" VerticalAlignment="Center" Margin="10">
                    <Label.Style>
                        <Style TargetType="Label">
                            <Setter Property="Foreground" Value="Transparent"/>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Expression}" Value="">
                                    <Setter Property="Foreground" Value="Gray"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Label.Style>
                </Label>
                <TextBox HorizontalAlignment="Stretch" Margin="5" Background="Transparent"
                 Text="{Binding Expression, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" Padding="5">
                </TextBox>
        </Grid>

এটি একটি পাঠ্যবক্স যা স্বচ্ছ ব্যাকগ্রাউন্ডের সাথে একটি লেবেল ওভারলেয়। লেবেলের ধূসর পাঠ্যটি একটি ডেটা ট্রিগার দ্বারা স্বচ্ছ হয়ে যায় যা যখনই আবদ্ধ পাঠ্য খালি স্ট্রিং ব্যতীত অন্য কোনও কিছু হয়ে থাকে তখন তা আগুন ধরে।


1

এছাড়াও, এই উত্তর দেখুন । আপনি ভিজুয়াল ব্রাশ এবং স্টাইলের কিছু ট্রিগার দিয়ে আরও সহজেই এটি সম্পাদন করতে পারেন:

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

এই স্টাইলটির পুনঃব্যবহারযোগ্যতা বাড়াতে, আপনি আসল কিউ ব্যানার পাঠ্য, রঙ, ওরিয়েন্টেশন ইত্যাদি নিয়ন্ত্রণ করতে সংযুক্ত বৈশিষ্ট্যের একটি সেটও তৈরি করতে পারেন


0

হাই আমি এই আচরণটি একটি আচরণের মধ্যে রেখেছি। সুতরাং আপনাকে কেবল আপনার পাঠ্যবক্সে এ জাতীয় কিছু যুক্ত করতে হবে

<i:Interaction.Behaviors>
         <Behaviors:TextBoxWatermarkBehavior Label="Test Watermark" LabelStyle="{StaticResource StyleWatermarkLabel}"/>
</i:Interaction.Behaviors>

আপনি আমার ব্লগ পোস্ট এখানে পেতে পারেন


0

আমার সমাধানটি বেশ সহজ।

আমার লগইন উইন্ডোতে। এক্সামলটি এরকম।

 <DockPanel HorizontalAlignment="Center" VerticalAlignment="Center" Height="80" Width="300" LastChildFill="True">
        <Button Margin="5,0,0,0" Click="login_Click" DockPanel.Dock="Right"  VerticalAlignment="Center" ToolTip="Login to system">
            Login
        </Button>
        <StackPanel>
            <TextBox x:Name="userNameWatermarked" Height="25" Foreground="Gray" Text="UserName" GotFocus="userNameWatermarked_GotFocus"></TextBox>
            <TextBox x:Name="userName" Height="25"  TextChanged="loginElement_TextChanged" Visibility="Collapsed" LostFocus="userName_LostFocus" ></TextBox>
            <TextBox x:Name="passwordWatermarked" Height="25" Foreground="Gray" Text="Password"  Margin="0,5,0,5" GotFocus="passwordWatermarked_GotFocus"></TextBox>
            <PasswordBox x:Name="password" Height="25" PasswordChanged="password_PasswordChanged" KeyUp="password_KeyUp" LostFocus="password_LostFocus" Margin="0,5,0,5" Visibility="Collapsed"></PasswordBox>
            <TextBlock x:Name="loginError" Visibility="Hidden" Foreground="Red" FontSize="12"></TextBlock>
        </StackPanel>
    </DockPanel>

কোডটি এরকম।

private void userNameWatermarked_GotFocus(object sender, RoutedEventArgs e)
    {
        userNameWatermarked.Visibility = System.Windows.Visibility.Collapsed;
        userName.Visibility = System.Windows.Visibility.Visible;
        userName.Focus();
    }

    private void userName_LostFocus(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(this.userName.Text))
        {
            userName.Visibility = System.Windows.Visibility.Collapsed;
            userNameWatermarked.Visibility = System.Windows.Visibility.Visible;
        }
    }

    private void passwordWatermarked_GotFocus(object sender, RoutedEventArgs e)
    {
        passwordWatermarked.Visibility = System.Windows.Visibility.Collapsed;
        password.Visibility = System.Windows.Visibility.Visible;
        password.Focus();
    }

    private void password_LostFocus(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(this.password.Password))
        {
            password.Visibility = System.Windows.Visibility.Collapsed;
            passwordWatermarked.Visibility = System.Windows.Visibility.Visible;
        }
    }

কেবল জলছবি পাঠ্যবক্সটি লুকানোর বা প্রদর্শন করার সিদ্ধান্ত নেওয়া যথেষ্ট। সুন্দর না হলেও ভাল কাজ করুন।


এটি একটি নিখুঁত উদাহরণ যা এটি কীভাবে করবেন না তা বর্ণনা করে, বিশেষত WPF- এর সাথে with
আলেকজান্দ্রু ডিকু

0

এই কৌশলটি প্লেসোল্ডার পাঠ্যবক্সটি প্রদর্শন / লুকিয়ে রাখতে পটভূমি সম্পত্তি ব্যবহার করে।
পাঠ্যবক্সে ফোকাস থাকলে স্থানধারক ইভেন্ট দেখানো হয়

কিভাবে এটা কাজ করে:

  • খালি হলে, পাঠ্যবক্সের পটভূমি প্লেসহোল্ডার পাঠ্যটি দেখানোর জন্য স্বচ্ছকে সেট করে।
  • যখন খালি পটভূমি প্লেসহোল্ডার পাঠ্য coverাকতে হোয়াইটে সেট করা থাকে না।

এখানে বেসিক উদাহরণ। আমার নিজের উদ্দেশ্যে আমি এটিকে একটি ইউজারকন্ট্রোল-এ পরিণত করেছি।

<Grid>
    <Grid.Resources>
        <ux:NotEmptyConverter x:Key="NotEmptyConverter" />

        <Style TargetType="{x:Type Control}" x:Key="DefaultStyle">
            <Setter Property="FontSize" Value="20" />
            <Setter Property="Margin" Value="10"/>
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="VerticalContentAlignment" Value="Center"></Setter>
        </Style>

        <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultStyle}"></Style>

    </Grid.Resources>

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" Text="Placeholder Text Is Here" Foreground="DarkGray" />
    <TextBox Grid.Row="0" Name="TextBoxEdit" 
            Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
        <TextBox.Style>
            <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultStyle}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=FirstName.Length, FallbackValue=0, TargetNullValue=0}" Value="0">
                        <Setter Property="Background" Value="Transparent"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=FirstName, FallbackValue=0, TargetNullValue=0, Converter={StaticResource NotEmptyConverter}}" Value="false">
                        <Setter Property="Background" Value="White"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>
</Grid>

ডেটাট্রিগারে খালি খালি স্ট্রিংগুলি সনাক্ত করতে এখানে ভ্যালু কনভার্টারটি রয়েছে।

public class NotEmptyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var s = value as string;
        return string.IsNullOrEmpty(s);
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

0

আপনি প্রবেশ করানো পাঠ্যের জন্য পৃথক মান রাখতে পারেন এবং এটি "গটফোকাস" এবং "লস্টফোকাস" ইভেন্টের পাঠ্য বাক্সের "পাঠ্য" ক্ষেত্রের সাথে সেট করতে পারেন। আপনি যখন ফোকাসটি পাবেন তখন কোনও মান না থাকলে আপনি পাঠ্য বাক্সটি সাফ করতে চাইবেন। এবং যখন আপনি ফোকাসটি হারাবেন, আপনি পাঠ্য বাক্স থেকে "পাঠ্য" মানটি সেট করতে এবং তারপরে পাঠ্য বাক্সের "পাঠ্য" মানটি স্থান ধারককে পুনরায় সেট করতে চান যদি এটি খালি থাকে।

private String username = "";

private void usernameTextBox_GotFocus(object sender, RoutedEventArgs e) {
  if (String.IsNullOrEmpty(username)) {
    usernameTextBox.Text = "";
  }
}

private void usernameTextBox_LostFocus(object sender, RoutedEventArgs e) {
  username = usernameTextBox.Text;
  if (String.IsNullOrEmpty(usernameTextBox.Text)) {
    usernameTextBox.Text = "Username";
  }
}

তারপরে আপনাকে কেবল তা নিশ্চিত করতে হবে যে পাঠ্য বাক্সের "পাঠ্য" মানটি স্থান ধারক পাঠকের সাথে আরম্ভ করা হয়েছে।

<TextBox x:Name="usernameTextBox" Text="Username" GotFocus="usernameTextBox_GotFocus" LostFocus="usernameTextBox_LostFocus" />

আপনি এটিকে আরও এমন ক্লাসে এক্সট্রাক্ট করতে পারেন যা "টেক্সটবক্স" শ্রেণিকে প্রসারিত করে এবং আপনার প্রকল্পের মাধ্যমে এটি পুনরায় ব্যবহার করতে পারে।

namespace UI {
  public class PlaceholderTextBox : TextBox {
    public String Value { get; set; }
    public String PlaceholderText { get; set; }
    public Brush PlaceholderBrush { get; set; }
    private Brush ValuedBrush { get; set; }

    public PlaceholderTextBox() : base() {}

    protected override void OnInitialized(EventArgs e) {
      base.OnInitialized(e);

      ValuedBrush = this.Foreground;

      if (String.IsNullOrEmpty(this.Text)) {
        this.Text = PlaceholderText;
        this.Foreground = PlaceholderBrush;
      }
    }

    protected override void OnGotFocus(System.Windows.RoutedEventArgs e) {
      this.Foreground = ValuedBrush;
      if (String.IsNullOrEmpty(Value)) {
        this.Text = "";
      }

      base.OnGotFocus(e);
    }

    protected override void OnLostFocus(System.Windows.RoutedEventArgs e) {
      Value = this.Text;
      if (String.IsNullOrEmpty(this.Text)) {
        this.Text = PlaceholderText;
        this.Foreground = PlaceholderBrush;
      }

      base.OnLostFocus(e);
    }
  }
}

এবং তারপরে এটি সরাসরি এক্সএএমএলে যুক্ত করা যেতে পারে।

<Window x:Class="UI.LoginWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:m="clr-namespace:UI"
        Initialized="Window_Initialized">
    <Grid>
        <m:PlaceholderTextBox x:Name="usernameTextBox" PlaceholderText="Username" PlaceholderBrush="Gray" />
    </Grid>
</Window>

0

যদি ওয়াটারমার্কের দৃশ্যমানতা নিয়ন্ত্রণের ফোকাসের অবস্থার উপর নির্ভর করে না, আপনি এটির উপর নির্ভর করতে চান যে ব্যবহারকারী কোনও পাঠ্য প্রবেশ করেছে কিনা, আপনি জন মাইজেজকের উত্তর ( OnWatermarkChangedনীচে থেকে ) আপডেট করতে পারেন

static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    var textbox = (TextBox)d;
    textbox.Loaded += UpdateWatermark;
    textbox.TextChanged += UpdateWatermark;
}

static void UpdateWatermark(object sender, RoutedEventArgs e) {
    var textbox = (TextBox)sender;
    var layer = AdornerLayer.GetAdornerLayer(textbox);
    if (layer != null) {
        if (textbox.Text == string.Empty) {
            layer.Add(new WatermarkAdorner(textbox, GetWatermark(textbox)));
        } else {
            var adorners = layer.GetAdorners(textbox);
            if (adorners == null) {
                return;
            }

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

আপনার পাঠ্যবক্সটি ফর্মটি প্রদর্শন করার সময় স্বয়ংক্রিয়ভাবে ফোকাস হয়ে যায় বা পাঠ্য সম্পত্তিটিতে ডেটাবাইন্ডিংয়ের পরে এটি আরও বেশি অর্থবোধ করে।

এছাড়াও যদি আপনার ওয়াটারমার্কটি সর্বদা কেবল একটি স্ট্রিং হয় এবং আপনার পাঠ্যবক্সের শৈলীর সাথে মেলে যদি আপনার জলছাপের স্টাইলের প্রয়োজন হয়, তবে অ্যাডোনারারে এটি করুন:

contentPresenter = new ContentPresenter {
    Content = new TextBlock {
        Text = (string)watermark,
        Foreground = Control.Foreground,
        Background = Control.Background,
        FontFamily = Control.FontFamily,
        FontSize = Control.FontSize,
        ...
    },
    ...
}

0

এখানে আমার পদ্ধতিরটি এমভিভিএমের জন্য দুর্দান্ত যেখানে আমি এটিও পরীক্ষা করে দেখি যে পাঠ্য বাক্সটিতে ফোকাস রয়েছে কিনা, আপনি কেবল পাঠ্য মানের জন্য একটি নিয়মিত ট্রিগারও ব্যবহার করতে পারেন পাশাপাশি বিন্দুটি হ'ল আমি ব্যাকগ্রাউন্ড পরিবর্তন করি যখন মান পরিবর্তন হয়:

                    <TextBox.Style>
                        <Style TargetType="TextBox">

                            <Style.Triggers>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="IsFocused" Value="True"/>
                                        <Condition Property="Text" Value=""/>
                                    </MultiTrigger.Conditions>
                                    <MultiTrigger.Setters>
                                        <Setter Property="Background">
                                            <Setter.Value>
                                                <ImageBrush ImageSource="/Images/Scan.PNG" Stretch="Uniform" AlignmentX="Left"/>
                                            </Setter.Value>
                                        </Setter>
                                    </MultiTrigger.Setters>
                                </MultiTrigger>

                            </Style.Triggers>
                        </Style>
                    </TextBox.Style>
                </TextBox>

0

আমি এটি একটি আচরণের মাধ্যমে সমাধান করার সিদ্ধান্ত নিয়েছি। এটি Hintপ্রদর্শনের জন্য পাঠ্যকে সংজ্ঞায়িত করার জন্য একটি সম্পত্তি ব্যবহার করে (আপনি যদি পছন্দ করেন তবে কোনও বস্তুও হতে পারে) এবং Valueইঙ্গিতটি দৃশ্যমান হওয়া উচিত বা না হওয়া উচিত ther

আচরণটি নিম্নরূপ ঘোষণা করা হয়েছে:

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

    public class HintBehavior : Behavior<ContentControl>
    {
        public static readonly DependencyProperty HintProperty = DependencyProperty
            .Register("Hint", typeof (string), typeof (HintBehavior)
            //, new FrameworkPropertyMetadata(null, OnHintChanged)
            );

        public string Hint
        {
            get { return (string) GetValue(HintProperty); }
            set { SetValue(HintProperty, value); }
        }

        public static readonly DependencyProperty ValueProperty = DependencyProperty
            .Register("Value", typeof (object), typeof (HintBehavior)
                , new FrameworkPropertyMetadata(null, OnValueChanged));

        private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var visible = e.NewValue == null;
            d.SetValue(VisibilityProperty, visible ? Visibility.Visible : Visibility.Collapsed);
        }

        public object Value
        {
            get { return GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        public static readonly DependencyProperty VisibilityProperty = DependencyProperty
            .Register("Visibility", typeof (Visibility), typeof (HintBehavior)
                , new FrameworkPropertyMetadata(Visibility.Visible
                    //, new PropertyChangedCallback(OnVisibilityChanged)
                    ));

        public Visibility Visibility
        {
            get { return (Visibility) GetValue(VisibilityProperty); }
            set { SetValue(VisibilityProperty, value); }
        }

        public static readonly DependencyProperty ForegroundProperty = DependencyProperty
            .Register("Foreground", typeof (Brush), typeof (HintBehavior)
                , new FrameworkPropertyMetadata(new SolidColorBrush(Colors.DarkGray)
                    //, new PropertyChangedCallback(OnForegroundChanged)
                    ));

        public Brush Foreground
        {
            get { return (Brush) GetValue(ForegroundProperty); }
            set { SetValue(ForegroundProperty, value); }
        }

        public static readonly DependencyProperty MarginProperty = DependencyProperty
            .Register("Margin", typeof (Thickness), typeof (HintBehavior)
                , new FrameworkPropertyMetadata(new Thickness(4, 5, 0, 0)
                    //, new PropertyChangedCallback(OnMarginChanged)
                    ));

        public Thickness Margin
        {
            get { return (Thickness) GetValue(MarginProperty); }
            set { SetValue(MarginProperty, value); }
        }


        private static ResourceDictionary _hintBehaviorResources;

        public static ResourceDictionary HintBehaviorResources
        {
            get
            {
                if (_hintBehaviorResources == null)
                {
                    var res = new ResourceDictionary
                    {
                        Source = new Uri("/Mayflower.Client.Core;component/Behaviors/HintBehaviorResources.xaml",
                            UriKind.RelativeOrAbsolute)
                    };
                    _hintBehaviorResources = res;
                }
                return _hintBehaviorResources;
            }
        }


        protected override void OnAttached()
        {
            base.OnAttached();
            var t = (ControlTemplate) HintBehaviorResources["HintBehaviorWrapper"];
            AssociatedObject.Template = t;
            AssociatedObject.Loaded += OnLoaded;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            AssociatedObject.Loaded -= OnLoaded;
            var label = (Label) AssociatedObject.Template.FindName("PART_HintLabel", AssociatedObject);
            label.DataContext = this;
            //label.Content = "Hello...";
            label.SetBinding(UIElement.VisibilityProperty, new Binding("Visibility") {Source = this, Mode = BindingMode.OneWay});
            label.SetBinding(ContentControl.ContentProperty, new Binding("Hint") {Source = this, Mode = BindingMode.OneWay});
            label.SetBinding(Control.ForegroundProperty, new Binding("Foreground") {Source = this, Mode = BindingMode.OneWay});
            label.SetBinding(FrameworkElement.MarginProperty, new Binding("Margin") {Source = this, Mode = BindingMode.OneWay});
        }
    }

এটি লক্ষ্যটিকে এটির নিজস্ব টেম্পলেট দিয়ে জড়িয়ে দেয়, এতে লেবেল যুক্ত করে:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ControlTemplate x:Key="HintBehaviorWrapper" TargetType="{x:Type ContentControl}">
        <Grid>
            <ContentPresenter Content="{TemplateBinding Content}" />
            <Label x:Name="PART_HintLabel" IsHitTestVisible="False" Padding="0" />
        </Grid>
    </ControlTemplate>
</ResourceDictionary>

এটি ব্যবহারের জন্য, কেবল এটি একটি আচরণ হিসাবে যুক্ত করুন এবং আপনার মানগুলি আবদ্ধ করুন (আমার ক্ষেত্রে আমি এটি একটি কন্ট্রোল টেম্পলেটটিতে যুক্ত করি, তাই বাধ্যতামূলক):

<ContentControl>
    <i:Interaction.Behaviors>
        <behaviors:HintBehavior Value="{Binding Property, RelativeSource={RelativeSource TemplatedParent}}"
                                                        Hint="{Binding Hint, RelativeSource={RelativeSource TemplatedParent}}" />
    </i:Interaction.Behaviors>
    <TextBox ... />
</ContentControl>

এটিকে একটি পরিষ্কার সমাধান হিসাবে বিবেচনা করা হলে আমি প্রতিক্রিয়াটি পছন্দ করব। এটিতে স্ট্যাটিক অভিধানের প্রয়োজন হয় না এবং তাই এর কোনও মেমরি ফাঁস হয় না।


0

খুব দ্রুত এবং সহজ উপায়ে এটি করার উপায়টি পেয়েছি

<ComboBox x:Name="comboBox1" SelectedIndex="0" HorizontalAlignment="Left" Margin="202,43,0,0" VerticalAlignment="Top" Width="149">
  <ComboBoxItem Visibility="Collapsed">
    <TextBlock Foreground="Gray" FontStyle="Italic">Please select ...</TextBlock>
  </ComboBoxItem>
  <ComboBoxItem Name="cbiFirst1">First Item</ComboBoxItem>
  <ComboBoxItem Name="cbiSecond1">Second Item</ComboBoxItem>
  <ComboBoxItem Name="cbiThird1">third Item</ComboBoxItem>
</ComboBox>

হতে পারে এটি এটি করার চেষ্টা করা যে কোনও ব্যক্তিকে সহায়তা করতে পারে

সূত্র: http://www.admindiaries.com/displaying-a-please-select-watermark-type-text-in-a-wpf-combobox/


0
namespace PlaceholderForRichTexxBoxInWPF
{
public MainWindow()
        {
            InitializeComponent();
            Application.Current.MainWindow.WindowState = WindowState.Maximized;// maximize window on load

            richTextBox1.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(rtb_GotKeyboardFocus);
            richTextBox1.LostKeyboardFocus += new KeyboardFocusChangedEventHandler(rtb_LostKeyboardFocus);
            richTextBox1.AppendText("Place Holder");
            richTextBox1.Foreground = Brushes.Gray;
        }
 private void rtb_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            if (sender is RichTextBox)
            {
                TextRange textRange = new TextRange(richTextBox1.Document.ContentStart, richTextBox1.Document.ContentEnd); 

                if (textRange.Text.Trim().Equals("Place Holder"))
                {
                    ((RichTextBox)sender).Foreground = Brushes.Black;
                    richTextBox1.Document.Blocks.Clear();
                }
            }
        }


        private void rtb_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            //Make sure sender is the correct Control.
            if (sender is RichTextBox)
            {
                //If nothing was entered, reset default text.
                TextRange textRange = new TextRange(richTextBox1.Document.ContentStart, richTextBox1.Document.ContentEnd); 

                if (textRange.Text.Trim().Equals(""))
                {
                    ((RichTextBox)sender).Foreground = Brushes.Gray;
                    ((RichTextBox)sender).AppendText("Place Holder");
                }
            }
        }
}

0
<TextBox Controls:TextBoxHelper.Watermark="Watermark"/>

আপনার প্রকল্পে mahapps.metro যুক্ত করুন। উইন্ডোতে উপরের কোড সহ পাঠ্যবক্স যুক্ত করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.