2012-04-03 15 views
8

एमएसडीएन दस्तावेज ब्राउज़ करते समय, आप इस मणि में आ सकते हैं: TextBox.Watermark।सिल्वरलाइट 4 में TextBox.Watermark का उपयोग कैसे करें?

"बहुत बढ़िया! मैं अपने टेक्स्ट बॉक्स पर वॉटरमार्किंग करने का एक अंतर्निहित तरीका चाहता हूं! यह बढ़िया है, मुझे आगे बढ़ने दें और इसे एक्सएएमएल में सेट करें!"

<TextBox Watermark="This is my watermark" Margin="20"></TextBox> 

दुर्भाग्यवश, अगर आप इस चलाते समय नहीं मिलेगा आप क्या उम्मीद:

enter image description here

और विस्तार: enter image description here

यह क्या है? खैर, एमएसडीएन दस्तावेज को बारीकी से देखें: enter image description here

यह सही है। यह सिल्वरलाइट 4 में समर्थित है, लेकिन यह भी कहता है "सिल्वरलाइट 4 एप्लिकेशन में उपयोग न करें"। यदि आप इसका उपयोग करते हैं, तो आपको सिस्टम.NotImplemented अपवाद प्राप्त होता है। सत्यापित करने के लिए, यहाँ संपत्ति परावर्तक के माध्यम से decompiled के लिए कोड है:

[EditorBrowsable(EditorBrowsableState.Never)] 
public object Watermark 
{ 
get 
{ 
StubHelper.ThrowIfNotInDesignMode(); 
return base.GetValue(WatermarkProperty); 
} 
set 
{ 
StubHelper.ThrowIfNotInDesignMode(); 
base.SetValue(WatermarkProperty, value); 
} 
} 

इसमें है - यह एक अपवाद किसी भी समय यह डिज़ाइन मोड में नहीं है फेंकता है। इसका कोई मतलब नहीं है? माइक्रोसॉफ्ट ऐसा क्यों करेगा?

दुर्भाग्यवश मुझे अभी तक कोई निश्चित उत्तर नहीं मिला है, हालांकि अगर मुझे लगता है कि ऐसा इसलिए है क्योंकि माइक्रोसॉफ्ट भविष्य के संस्करण (शायद v5) में टेक्स्टबॉक्स नियंत्रण पर वॉटरमार्क व्यवहार को लागू करने की योजना बना रहा है और प्रभावी रूप से इस संपत्ति को आरक्षित करना चाहता था इसलिए तीसरे पक्ष के नियंत्रण निर्माता टेक्स्टबॉक्स को उपclass नहीं करते हैं और अपनी खुद की वॉटरमार्क संपत्ति बनाते हैं। मुझे कम से कम एक नियंत्रण विक्रेता, घटक का पता है, जिसका नियंत्रण टेक्स्टबॉक्स से प्राप्त होता है और वॉटरमार्क संपत्ति प्रदान करता है। मेरे लिए, ऐसा लगता है कि यह माइक्रोसॉफ्ट का इस संपत्ति नाम का उपयोग अपने टेक्स्टबॉक्स उप-वर्गों पर करने से लोगों को हतोत्साहित करने का तरीका है।

उत्तर

14

वन क्लास लाइब्रेरी प्रोजेक्ट बनाएं। कक्षा फ़ाइल जोड़ें निम्नलिखित कोड का उपयोग करें ..... उसके बाद इस परियोजना में अपनी परियोजना में जोड़ें।

public class WatermarkTextBox : TextBox 
{ 
    private bool displayWatermark = true; 
    private bool hasFocus = false; 
    public WatermarkTextBox() 
    { 
     this.GotFocus += new RoutedEventHandler(WatermarkTextBox_GotFocus); 
     this.LostFocus += new RoutedEventHandler(WatermarkTextBox_LostFocus); 
     this.TextChanged += new TextChangedEventHandler(WatermarkTextBox_TextChanged); 
     this.Unloaded += new RoutedEventHandler(WatermarkTextBox_Unloaded); 
    } 

    private void WatermarkTextBox_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     if (!hasFocus && Text == "") 
     { 
      setMode(true); 
      displayWatermark = true; 
      this.Text = Watermark; 
     } 
    } 

    private void WatermarkTextBox_Unloaded(object sender, RoutedEventArgs e) 
    { 
     this.GotFocus -= WatermarkTextBox_GotFocus; 
     this.LostFocus -= WatermarkTextBox_LostFocus; 
     this.Unloaded -= WatermarkTextBox_Unloaded; 
     this.TextChanged -= WatermarkTextBox_TextChanged; 
    } 

    private void WatermarkTextBox_GotFocus(object sender, RoutedEventArgs e) 
    { 
     hasFocus = true; 
     if (displayWatermark) 
     { 
      setMode(false); 
      this.Text = ""; 
     } 
    } 
    private void WatermarkTextBox_LostFocus(object sender, RoutedEventArgs e) 
    { 
     hasFocus = false; 
     if (this.Text == "") 
     { 
      displayWatermark = true; 
      setMode(true); 
      this.Text = Watermark; 
     } 
     else 
     { 
      displayWatermark = false; 
     } 
    } 
    private void setMode(bool watermarkStyle) 
    { 
     if (watermarkStyle) 
     { 
      this.FontStyle = FontStyles.Italic; 
      this.Foreground = new SolidColorBrush(Colors.Gray); 
     } 
     else 
     { 
      this.FontStyle = FontStyles.Normal; 
      this.Foreground = new SolidColorBrush(Colors.Black); 
     } 
    } 
    public new string Watermark 
    { 
     get { return GetValue(WatermarkProperty) as string; } 
     set { SetValue(WatermarkProperty, value); } 
    } 
    public static new readonly DependencyProperty WatermarkProperty = 
     DependencyProperty.Register("Watermark", typeof(string), typeof(WatermarkTextBox), new PropertyMetadata(watermarkPropertyChanged)); 
    private static void watermarkPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     WatermarkTextBox textBox = obj as WatermarkTextBox; 
     if (textBox.displayWatermark) 
     { 
      textBox.Text = e.NewValue.ToString(); 
      textBox.setMode(true); 
     } 
    } 

XAML:

xmlns:watertext="clr-namespace:SilverlightClassLibrary1;assembly=SilverlightClassLibrary1" 


    <watertext:WatermarkTextBox Watermark="WElcome" Margin="150,115,120,166"></watertext:WatermarkTextBox> 
+0

+1 चेक आउट । रास्ते में सिल्वरलाइट 5 में ठीक काम करता है। ध्यान दें कि एसएल 5 एमएसडीएन दस्तावेज में अभी भी वॉटरमार्क संपत्ति के बारे में एक ही विरोधाभासी जानकारी है। –

+0

ध्यान दें कि वॉटरमार्क संपत्ति सेट नहीं होने पर मुख्य रूप से डिज़ाइन-टाइम त्रुटि को हल करने के लिए मैंने कोड को थोड़ा tweaked किया। अपडेट किया गया कोड नीचे दिए गए नए उत्तर के रूप में जोड़ा गया। –

+0

आपने कन्स्ट्रक्टर में ईवेंट में पंजीकृत किया है, लेकिन अनलोड में आप उनसे अनियंत्रित हैं (जो ठीक है), लेकिन इससे टैब नियंत्रण में समस्याएं आती हैं, टैब नियंत्रण इसकी सामग्री को उतार देगा और उचित टैब दबाए जाने पर लोड होगा, इसलिए शायद आपको कन्स्ट्रक्टर के बजाय लोडेड इवेंट में ईवेंट में पंजीकरण करें। – Sonosar

2

वैसे आप इसे सफलतापूर्वक सिल्वरलाइट में उपयोग कर सकते हैं 5

इस लिंक आज़माएं: TextBox.Watermark

मैं सफलतापूर्वक एक सिल्वरलाइट 5 में WatermarkTextBox उपयोग कर रहा हूँ एमवीवीएम आवेदन।

3

मैंने वॉटरमार्क संपत्ति सेट नहीं होने पर डिज़ाइन-टाइम त्रुटि को ठीक करने के लिए @ मनी कंदन के समाधान को थोड़ा संशोधित किया। इसके अलावा एक हैस्वेलू बुलियन संपत्ति भी आसानी से जांचने में सक्षम है कि क्या उपयोगकर्ता ने टेक्स्टबॉक्स में टेक्स्ट दर्ज किया है, और आखिरकार सभी-व्हाइटस्पेस प्रविष्टियों को गैर-प्रविष्टियों के रूप में बदलने के लिए बदल दिया गया है (यानी, वॉटरमार्क प्रदर्शित करना जारी रखें)।

संशोधित कोड:

public class WatermarkTextBox : TextBox 
{ 

    private bool displayWatermark = true; 
    private bool hasFocus = false; 

    public WatermarkTextBox() 
    { 
     this.GotFocus += new RoutedEventHandler(WatermarkTextBox_GotFocus); 
     this.LostFocus += new RoutedEventHandler(WatermarkTextBox_LostFocus); 
     this.TextChanged += new TextChangedEventHandler(WatermarkTextBox_TextChanged); 
     this.Unloaded += new RoutedEventHandler(WatermarkTextBox_Unloaded); 
    } 

    private void WatermarkTextBox_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     if (!hasFocus && string.IsNullOrWhiteSpace(this.Text)) 
     { 
      setMode(true); 
      displayWatermark = true; 
      // avoid design-time error if Watermark not specified 
      this.Text = (Watermark == null ? string.Empty : Watermark); 
     } 
    } 

    private void WatermarkTextBox_Unloaded(object sender, RoutedEventArgs e) 
    { 
     this.GotFocus -= WatermarkTextBox_GotFocus; 
     this.LostFocus -= WatermarkTextBox_LostFocus; 
     this.Unloaded -= WatermarkTextBox_Unloaded; 
     this.TextChanged -= WatermarkTextBox_TextChanged; 
    } 

    private void WatermarkTextBox_GotFocus(object sender, RoutedEventArgs e) 
    { 
     hasFocus = true; 
     if (displayWatermark) 
     { 
      setMode(false); 
      this.Text = ""; 
     } 
    } 

    private void WatermarkTextBox_LostFocus(object sender, RoutedEventArgs e) 
    { 
     hasFocus = false; 
     if (string.IsNullOrWhiteSpace(this.Text)) 
     { 
      displayWatermark = true; 
      setMode(true); 
      this.Text = (Watermark == null ? string.Empty : Watermark); 
     } 
     else 
     { 
      displayWatermark = false; 
     } 
    } 

    private void setMode(bool watermarkStyle) 
    { 
     if (watermarkStyle) 
     { 
      this.FontStyle = FontStyles.Italic; 
      this.Foreground = new SolidColorBrush(Colors.Gray); 
     } 
     else 
     { 
      this.FontStyle = FontStyles.Normal; 
      this.Foreground = new SolidColorBrush(Colors.Black); 
     } 
    } 

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

    public static new readonly DependencyProperty WatermarkProperty = 
     DependencyProperty.Register("Watermark", typeof(string), typeof(WatermarkTextBox), new PropertyMetadata(watermarkPropertyChanged)); 
    private static void watermarkPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     WatermarkTextBox textBox = obj as WatermarkTextBox; 
     if (textBox.displayWatermark) 
     { 
      textBox.Text = e.NewValue.ToString(); 
      textBox.setMode(true); 
     } 
    } 

    public bool HasValue 
    { 
     get 
     { 
      // if watermark has been specified, then compare to text value to determine if text set by user, 
      // otherwise check to see if empty or whitespace. 
      if (this.Watermark != null) 
       return this.Watermark != this.Text; 
      else 
       return !string.IsNullOrWhiteSpace(this.Text); 
     } 
    } 

} 
2

एक वर्ग पुस्तकालय परियोजना बनाएँ।कक्षा फ़ाइल में निम्न कोड का उपयोग करें

using System; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Ink; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 

namespace Project.Controls 
{ 
    public class WatermarkEditBox : TextBox 
    { 

     TextBlock lbl = new TextBlock() 
     { 
      IsHitTestVisible = false, 
      Foreground = new SolidColorBrush(Colors.LightGray), 
      VerticalAlignment = VerticalAlignment.Center, 
      HorizontalAlignment = HorizontalAlignment.Left, 
      Margin = new Thickness(3,0,0,0) 
     }; 
     public string WatermarkText { get { return lbl.Text; } set { lbl.Text = value; } } 

     public WatermarkEditBox() 
     { 
      this.Loaded += WatermarkEditBox_Loaded; 
     } 

     void WatermarkEditBox_Loaded(object sender, RoutedEventArgs e) 
     { 
      this.UpdateLayout(); 
      Grid g = GetObjectOfType<Grid>(this, "RootElement"); 
      if (g != null) 
      { 
       g.Children.Add(lbl); 
      } 
      this.TextChanged += WatermarkEditBox_TextChanged; 
     } 

     void WatermarkEditBox_TextChanged(object sender, TextChangedEventArgs e) 
     { 
      if (this.Text.Length == 0) 
       lbl.Visibility = System.Windows.Visibility.Visible; 
      else 
       lbl.Visibility = System.Windows.Visibility.Collapsed; 
     } 

     public TObject GetObjectOfType<TObject>(DependencyObject parent, string name) where TObject : DependencyObject 
     { 
      int count = VisualTreeHelper.GetChildrenCount(parent); 
      for (int i = 0; i < count; ++i) 
      { 
       DependencyObject child = VisualTreeHelper.GetChild(parent, i); 
       if (child is TObject && child.GetValue(NameProperty).ToString() == name) 
       { 
        return child as TObject; 
       } 
       else 
       { 
        TObject obj = GetObjectOfType<TObject>(child, name); 
        if (obj != null) 
        { 
         return obj; 
        } 
       } 
      } 

      return null; 
     } 

    } 
} 

XAML:

xmlns:Controls="clr-namespace:Project.Controls" 

<Controls:WatermarkEditBox WatermarkText="фильтр" Width="100"/> 
2

यह एक बहुत अच्छा समाधान के लिए व्यवहार

namespace MyNamespace 
{ 
    public class WatermarkBehavior : Behavior<TextBox> 
    { 
     public String Watermark 
     { 
      get { return this.GetValue(WatermarkProperty) as String; } 
      set { this.SetValue(WatermarkProperty, value); } 
     } 

     public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(String), typeof(WatermarkBehavior), new PropertyMetadata("", new PropertyChangedCallback(OnWatermarkChanged))); 

     private static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var behavior = d as WatermarkBehavior; 
      if (!String.IsNullOrWhiteSpace(e.NewValue as String)) 
      { 
       behavior.SetWatermarkIfNeeded(); 
      } 
     } 

     protected override void OnAttached() 
     { 
      base.OnAttached(); 
      this.AssociatedObject.GotFocus += GotFocus; 
      this.AssociatedObject.LostFocus += LostFocus; 
     } 

     protected override void OnDetaching() 
     { 
      base.OnDetaching(); 
      this.AssociatedObject.GotFocus -= GotFocus; 
      this.AssociatedObject.LostFocus -= LostFocus; 
     } 

     private void GotFocus(object sender, RoutedEventArgs e) 
     { 
      if (this.AssociatedObject.Text == this.Watermark) 
      { 
       this.AssociatedObject.Text = String.Empty; 
       this.AssociatedObject.Foreground = new SolidColorBrush(Colors.Black); 
      } 
     } 

     private void LostFocus(object sender, RoutedEventArgs e) 
     { 
      this.SetWatermarkIfNeeded(); 
     } 

     private void SetWatermarkIfNeeded() 
     { 
      if (String.IsNullOrWhiteSpace(this.AssociatedObject.Text)) 
      { 
       this.SetWatermark(); 
      } 
     } 

     private void SetWatermark() 
     { 
      this.AssociatedObject.Text = this.Watermark; 
      this.AssociatedObject.Foreground = new SolidColorBrush(Colors.Gray); 
     } 
    } 
} 

के आधार पर XAML

<UserControl x:Class="GreenField.Targeting.Controls.BasketTargets.EditorView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:MyNamespace" 
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> 
    <TextBox Text="{Binding Text}"> 
    <i:Interaction.Behaviors> 
     <local:WatermarkBehavior Watermark="{Binding Watermark}" /> 
    </i:Interaction.Behaviors> 
    </TextBox> 
</UserControl>