++ ++
This article is original on this site. You are welcome to repost it! Reprinted please indicate the source:
Http://blog.csdn.net/mr_raptor/article/details/7251992
++ ++
Declaration: this control is modified based on watermarkedtextbox.
- Download the watermarkedtextboxcontrol from http://www.windowsphonegeek.com/articles/wp7-watermarkedtextbox-custom-control.
Address: http://blog.csdn.net/mr_raptor/article/details/7251992
Principle Analysis:
Adding a watermark after passwordbox is similar to adding a watermark after textbox. The following requirements apply:
- When there is no content in passwordbox, the watermark is displayed.
- When there is content in passwordbox, the watermark is not displayed, but the content is displayed.
The simplest idea is to add a textblock-like control behind the passwordbox control, and then rewrite the focus callback method. When there is a focus, the watermark is not displayed and there is no focus point, determines whether to display the watermark based on whether there is content.
The idea is as above. Next we will analyze the watermarkedtextbox code to see if the author has the same idea as ours.
I. Analyze watermarkedtextbox code
- Themes/generic. XAML
The style file of the custom control must be named after generic. XAML and placed in the themes directory.
<Controltemplate X: Key = "phonedisabledtextboxtemplate" targettype = "textbox"> <br/> <contentcontrol X: name = "contentelement" borderthickness = "0" comment = "stretch" margin = "{staticresource details}" padding = "{templatebinding padding}" verticalcontentalignment = "stretch"/> <br /> </controltemplate> <br/> <style targettype = "Local: watermarkedtextbox "> <br/> <setter property =" template "> <br/> <setter. value> <br/> <controltemplate targettype = "Local: watermarkedtextbox"> <br/> <grid background = "Transparent"> <br/> <border X: name = "enabledborder"> <br/> <grid> <br/> <contentcontrol X: name = "watermarkcontent" style = "{templatebinding watermarkstyle}" content = "{templatebinding watermark}" background = "Transparent" opacity = "0.5"/> <br/> <contentcontrol x: name = "contentelement" borderthickness = "0" verticalcontentalignment = "stretch"/> <br/> </GRID> <br/> </Border> <br/> <border x: name = "disabledorreadonlyborder" background = "Transparent" visibility = "Collapsed"> <br/> <textbox X: name = "disabledorreadonlycontent" background = "Transparent" isreadonly = "true" text = "{templatebinding text}" template = "{staticresource phonedisabledtextboxtemplate}"/> <br/> </border> <br/> </GRID> <br/> </controltemplate> <br/> </setter. value> <br/> </setter> <br/> </style>
Note: Some irrelevant code is omitted above.
Http://blog.csdn.net/mr_raptor/article/details/7251992
The above XAML file defines the watermarkedtextbox style:
- A controltemplate element is defined at the beginning of the file. It is known from the first two sections that it is used to set a template for a control. It can be seen from the targettype = "textbox" that is used to control the textbox type, it defines a contentcontrol class named contentelement.
- Targettype = "Local: watermarkedtextbox" shows that it is a control style for watermarkedtextbox.
- Two content control elements are defined in enabledborder: watermarkcontent and contentelement. watermarkcontent is bound with the dependency attribute watermark (declared in watermarktextbox. CS ).
- In the following disabledorreadonlyborder, A Textbox Control is bound to the text attribute in the watermarkedtextbox. In the Textbox Control, the template is set to phonedisabledtextboxtemplate, you can set the watermarkedtextbox property to disabled. Then, the watermark disappears and the original Textbox Control is displayed.
2. watermarktextbox. CS
Namespace watermarkedtextboxcontrol <br/>{< br/> public class watermarkedtextbox: textbox <br/>{< br/> contentcontrol watermarkcontent; <br/> Public static readonly dependencyproperty watermarkproperty = <br/> dependencyproperty. register ("watermark", typeof (object), typeof (watermarkedtextbox), new propertymetadata (onwatermarkpropertychanged); </P> <p> Public static readonly dependencyproperty watermark Styleproperty = <br/> dependencyproperty. register ("watermarkstyle", typeof (style), typeof (watermarkedtextbox), null ); </P> <p> Public style watermarkstyle <br/> {<br/> get {return base. getvalue (watermarkstyleproperty) as style ;}< br/> set {base. setvalue (watermarkstyleproperty, value) ;}< br/>}</P> <p> Public object watermark <br/>{< br/> get {return base. getvalue (watermarkproperty) as object;} <br/> S Et {base. setvalue (watermarkproperty, value) ;}< br/>}</P> <p> Public watermarkedtextbox () <br/>{< br/> defaultstylekey = typeof (watermarkedtextbox ); <br/>}</P> <p> Public override void onapplytemplate () <br/>{< br/> base. onapplytemplate (); <br/> This. watermarkcontent = This. gettemplatechild ("watermarkcontent") as contentcontrol; <br/> If (watermarkcontent! = NULL) <br/>{< br/> determinewatermarkcontentvisibility (); <br/>}</P> <p> protected override void ongotfocus (routedeventargs e) <br/>{< br/> If (watermarkcontent! = NULL & string. isnullorempty (this. text) <br/>{< br/> This. watermarkcontent. visibility = visibility. collapsed; <br/>}< br/> base. ongotfocus (E); <br/>}</P> <p> protected override void onlostfocus (routedeventargs e) <br/>{< br/> If (watermarkcontent! = NULL & string. isnullorempty (this. text) <br/>{< br/> This. watermarkcontent. visibility = visibility. visible; <br/>}< br/> base. onlostfocus (E); <br/>}</P> <p> Private Static void onwatermarkpropertychanged (dependencyobject sender, dependencypropertychangedeventargs ARGs) <br/>{< br/> watermarkedtextbox watermarktextbox = sender as watermarkedtextbox; <br/> If (watermarktextbox! = NULL & watermarktextbox. watermarkcontent! = NULL) <br/>{< br/> watermarktextbox. determinewatermarkcontentvisibility (); <br/>}</P> <p> private void determinewatermarkcontentvisibility () <br/>{< br/> If (string. isnullorempty (this. text) <br/>{< br/> This. watermarkcontent. visibility = visibility. visible; <br/>}< br/> else <br/>{< br/> This. watermarkcontent. visibility = visibility. collapsed; <br/>}< br/>
Address: http://blog.csdn.net/mr_raptor/article/details/7251992
We can see from the watermarkedtextbox class:
- It inherits the textbox class
- Added the watermark and watermarkstyle dependency attributes to set the watermark content and style. added the attribute change event onwatermarkpropertychanged to the watermark attribute.
- The onapplytemplate method is overloaded to obtain the generic. reference the element declared in the XAML file: watermarkcontent, and according to generic. textbox: disabledorreadonlycontent in XAML to obtain whether there is content in it. If there is content, watermarkcontent is invisible; otherwise, watermarkcontent is visible.
- Ongotfocus and onlostfocus are reloaded. When the custom control gets the focus, set watermarkcontent to invisible; otherwise, watermarkcontent is visible.
The above analysis shows that when the user sets the watermark attribute of the custom control, the onwatermarkpropertychanged method of the callback registration is used to determine whether there is content in the watermarkcontent. If yes, watermarkcontent is invisible; otherwise, watermarkcontent is visible. In addition, when ongotfocus and onlostfocus are reloaded, you must determine whether to set watermarkcontent to visible when you get or lose the focus.
Ii. Custom watermarkedpasswordbox
Based on the previous analysis, we can try to make the following changes:
- Create a watermarkedpasswordbox class
- Copy watermarktextbox. CS to the watermarkedpasswordbox class and change the class name so that watermarkedpasswordbox inherits the password class.
- In themes/generic. in XAML, copy all the code in <style targettype = "Local: watermarkedpasswordbox"> and change it to the watermarkedpasswordbox code. Modify the intermediate details and we do not plan to support the disabled attribute, so you can remove disabledorreadonlyborder and replace contentelement in enabledborder with passwordbox. The name is still contentelement.
During compilation, an error occurs: This. Text in watermarkedpasswordbox has an error. This is because the password does not have the text attribute and has a Password attribute, so make the following changes:
- Let the watermarkedpasswordbox class inherit Textbox, but add an attribute: passwordcontent of the passwordbox type
- In the onapplytemplate method, obtain the reference contentelement of the Self-added passwordbox control and add the passwordchanged event to the passwordbox control. When the content in the password box changes, set the text attribute value of the textbox to passwordbox. password Value
- Similarly, in the XAML Style File, add Password = "{templatebinding text}" to the passwordbox control }"
The modified code is as follows:
XAML:
<Style targettype = "Local: watermarkedpasswordbox"> <br/> <setter property = "template"> <br/> <setter. value> <br/> <controltemplate targettype = "Local: watermarkedpasswordbox"> <br/> <grid background = "Transparent"> <br/> <border X: name = "enabledborder" borderbrush = "{templatebinding borderbrush}" borderthickness = "{templatebinding borderthickness}" background = "{your background}" margin = "{staticresource succeeded}"> <br /> <grid> <br/> <contentcontrol X: name = "watermarkcontent" style = "{templatebinding watermarkstyle}" content = "{templatebinding watermark}" background = "Transparent" opacity = "0.5"/> <br/> <passwordbox x: name = "contentelement" background = "Transparent" <br/> Password = "{templatebinding text}" <br/> borderthickness = "0" horizontalcontentalignment = "stretch" <br/> margin = "-12, -12,-12, -12 "<br/> verticalcontentalignment =" stretch "/> <br/> </GRID> <br/> </Border> <br/> </GRID> <br /> </controltemplate> <br/> </setter. value> <br/> </setter> <br/> </style>
Address: http://blog.csdn.net/mr_raptor/article/details/7251992
C #:
Public class watermarkedpasswordbox: textbox <br/>{< br/> contentcontrol watermarkcontent; <br/> private passwordbox passwordcontent; </P> <p> Public object watermark <br/> {<br/> get {return base. getvalue (watermarkproperty) as object;} <br/> set {base. setvalue (watermarkproperty, value) ;}< br/>}< br/> Public static readonly dependencyproperty watermarkproperty = <br/> dependencyproperty. regis Ter ("watermark", typeof (object), typeof (watermarkedpasswordbox), new propertymetadata (onwatermarkpropertychanged); </P> <p> Private Static void onwatermarkpropertychanged (dependencyobject sender, dependencypropertychangedeventargs ARGs) <br/>{< br/> watermarkedpasswordbox watermarktextbox = sender as watermarkedpasswordbox; <br/> If (watermarktextbox! = NULL & watermarktextbox. watermarkcontent! = NULL) <br/>{< br/> watermarktextbox. determinewatermarkcontentvisibility (); <br/>}</P> <p> debug. writeline ("onwatermarkpropertychanged"); <br/>}</P> <p> Public style watermarkstyle <br/>{< br/> get {return base. getvalue (watermarkstyleproperty) as style ;}< br/> set {base. setvalue (watermarkstyleproperty, value) ;}< br/>}< br/> Public static readonly dependencyproperty watermarkstyleproperty = <Br/> dependencyproperty. register ("watermarkstyle", typeof (style), typeof (watermarkedpasswordbox), null); </P> <p> Public watermarkedpasswordbox () <br/>{< br/> defaultstylekey = typeof (watermarkedpasswordbox); <br/>}</P> <p> Public override void onapplytemplate () <br/>{< br/> base. onapplytemplate (); <br/> This. watermarkcontent = This. gettemplatechild ("watermarkcontent") as contentcontrol; <br/> th Is. passwordcontent = This. gettemplatechild ("contentelement") as passwordbox; <br/> If (watermarkcontent! = NULL & watermarkcontent! = NULL) <br/>{< br/> passwordcontent. passwordchanged + = new routedeventhandler (passwordcontent_passwordchanged); <br/> Reset (); <br/>}</P> <p> void passwordcontent_passwordchanged (Object sender, routedeventargs e) <br/>{< br/> passwordbox passwdbx = sender as passwordbox; <br/> This. TEXT = passwdbx. password; <br/>}</P> <p> protected override void ongotfocus (R Outedeventargs e) <br/>{< br/> If (watermarkcontent! = NULL & watermarkcontent! = NULL & string. isnullorempty (this. passwordcontent. password) <br/>{< br/> This. watermarkcontent. visibility = visibility. collapsed; <br/>}< br/> base. ongotfocus (E); <br/>}</P> <p> protected override void onlostfocus (routedeventargs e) <br/>{< br/> If (watermarkcontent! = NULL & watermarkcontent! = NULL & string. isnullorempty (this. passwordcontent. password) <br/>{< br/> This. watermarkcontent. visibility = visibility. visible; <br/>}< br/> base. onlostfocus (E); <br/>}</P> <p> private void determinewatermarkcontentvisibility () <br/>{< br/> If (string. isnullorempty (this. passwordcontent. password) <br/>{< br/> This. watermarkcontent. visibility = visibility. visible; <br/>}< br/> else <br/>{< br/> This. watermarkcontent. visibility = visibility. collapsed; <br/>}< br/>}
After compilation, the generated library is introduced into the demo program, and the control is added. The result is as follows.
On the left, no content is entered. the watermark is displayed. On the right, the effect is displayed when the content is entered.
++ ++
This article is original on this site. You are welcome to repost it! Reprinted please indicate the source:
Http://blog.csdn.net/mr_raptor/article/details/7251992
++ ++