1: using System;
2: using System.Diagnostics;
3: using System.Diagnostics.CodeAnalysis;
4: using System.Web.Security;
5: using System.Web.UI;
6: using System.Web.UI.HtmlControls;
7: using System.Web.UI.WebControls;
8: using System.Web.UI.WebControls.Adapters;
9:
10: /// <summary>
11: /// Implements a custom control adapter for the ASP.NET <see cref="Login"/>
12: /// control that produces CSS-friendly HTML.
13: /// </summary>
14: public class LoginAdapter : WebControlAdapter {
15: /// <summary>
16: /// The container <see cref="Control"/> that contains the
17: /// <see cref="Login"/> control's template.
18: /// </summary>
19: private Control container;
20:
21: /// <summary>
22: /// The value entered into the password text box.
23: /// </summary>
24: private string passwordValue;
25:
26: /// <summary>
27: /// The value of the remember me check box.
28: /// </summary>
29: private bool rememberMeValue;
30:
31: /// <summary>
32: /// The value entered into the user name text box.
33: /// </summary>
34: private string userNameValue;
35:
36: /// <summary>
37: /// Creates the child controls for the <see cref="Login"/> control.
38: /// </summary>
39: protected override void CreateChildControls() {
40: base.CreateChildControls();
41:
42: Login login = Control as Login;
43: Debug.Assert(login != null, "login != null");
44:
45: ITemplate layoutTemplate = login.LayoutTemplate;
46: if (layoutTemplate == null) {
47: layoutTemplate = new DefaultLoginTemplate(login);
48: }
49:
50: container = new Control();
51: layoutTemplate.InstantiateIn(container);
52: login.Controls.Clear();
53: login.Controls.Add(container);
54:
55: IEditableTextControl userName = container.FindControl("UserName") as
56: IEditableTextControl;
57: Debug.Assert(userName != null, "userName != null");
58: userName.TextChanged += UserName_TextChanged;
59:
60: IEditableTextControl password = container.FindControl("Password") as
61: IEditableTextControl;
62: Debug.Assert(password != null, "password != null");
63: password.TextChanged += Password_TextChanged;
64:
65: ICheckBoxControl rememberMe = container.FindControl("RememberMe") as
66: ICheckBoxControl;
67: Debug.Assert(rememberMe != null, "rememberMe != null");
68: rememberMe.CheckedChanged += RememberMe_CheckedChanged;
69: }
70:
71: /// <summary>
72: /// Creates the child controls that will be used to render the
73: /// contents of the <see cref="Login"/> control.
74: /// </summary>
75: /// <param name="e">The event arguments.</param>
76: protected override void OnInit(EventArgs e) {
77: base.OnInit(e);
78:
79: Login login = Control as Login;
80: Debug.Assert(login != null, "login != null");
81: login.Authenticate += login_Authenticate;
82: login.LoginError += login_LoginError;
83: }
84:
85: /// <summary>
86: /// Sets the text and check box settings for the user name, password,
87: /// and remember me fields on the login form.
88: /// </summary>
89: /// <param name="e">The event arguments.</param>
90: protected override void OnLoad(EventArgs e) {
91: base.OnLoad(e);
92:
93: if (!Page.IsPostBack) {
94: Login login = Control as Login;
95: Debug.Assert(login != null, "login != null");
96:
97: userNameValue = login.UserName;
98: passwordValue = "";
99: rememberMeValue = login.RememberMeSet;
100: }
101: }
102:
103: /// <summary>
104: /// Sets the value of the user name text box and the remember me
105: /// checkbox before the control is rendered.
106: /// </summary>
107: /// <param name="e"></param>
108: protected override void OnPreRender(EventArgs e) {
109: IEditableTextControl userName = container.FindControl("UserName") as
110: IEditableTextControl;
111: Debug.Assert(userName != null, "userName != null");
112: userName.Text = userNameValue;
113:
114: IEditableTextControl password = container.FindControl("Password") as
115: IEditableTextControl;
116: Debug.Assert(password != null, "password != null");
117: password.Text = "";
118:
119: ICheckBoxControl rememberMe = container.FindControl("RememberMe") as
120: ICheckBoxControl;
121: Debug.Assert(rememberMe != null, "rememberMe != null");
122: rememberMe.Checked = rememberMeValue;
123: }
124:
125: /// <summary>
126: /// Detaches the adapter from the <see cref="Login.LoginError"/> event.
127: /// </summary>
128: /// <param name="e">The event arguments.</param>
129: protected override void OnUnload(EventArgs e) {
130: Login login = Control as Login;
131: Debug.Assert(login != null, "login != null");
132: login.Authenticate -= login_Authenticate;
133: login.LoginError -= login_LoginError;
134:
135: IEditableTextControl userName = container.FindControl("UserName") as
136: IEditableTextControl;
137: Debug.Assert(userName != null, "userName != null");
138: userName.TextChanged -= UserName_TextChanged;
139:
140: IEditableTextControl password = container.FindControl("Password") as
141: IEditableTextControl;
142: Debug.Assert(password != null, "password != null");
143: password.TextChanged -= Password_TextChanged;
144:
145: ICheckBoxControl rememberMe = container.FindControl("RememberMe") as
146: ICheckBoxControl;
147: Debug.Assert(rememberMe != null, "rememberMe != null");
148: rememberMe.CheckedChanged -= RememberMe_CheckedChanged;
149:
150: base.OnUnload(e);
151: }
152:
153: /// <summary>
154: /// Prevents the login control from rendering if the user is
155: /// authenticated and the <see cref="Login.VisibleWhenLoggedIn"/>
156: /// property is set to false.
157: /// </summary>
158: /// <param name="writer">
159: /// The <see cref="HtmlTextWriter"/> object to use to render the
160: /// <see cref="Login"/> control.
161: /// </param>
162: protected override void Render(HtmlTextWriter writer) {
163: Login login = Control as Login;
164: Debug.Assert(login != null, "login != null");
165:
166: if (!Page.Request.IsAuthenticated || login.VisibleWhenLoggedIn) {
167: base.Render(writer);
168: }
169: }
170:
171: /// <summary>
172: /// Renders the opening tag that encapsulates the <see cref="Login"/>
173: /// control's content.
174: /// </summary>
175: /// <param name="writer">
176: /// The <see cref="HtmlTextWriter"/> object to use to output the
177: /// opening tag for the control.
178: /// </param>
179: protected override void RenderBeginTag(HtmlTextWriter writer) {
180: Login login = Control as Login;
181: Debug.Assert(login != null, "login != null");
182:
183: writer.AddAttribute(HtmlTextWriterAttribute.Id, login.ClientID);
184:
185: if (!login.ControlStyle.IsEmpty) {
186: if (!String.IsNullOrEmpty(login.ControlStyle.CssClass)) {
187: writer.AddAttribute(HtmlTextWriterAttribute.Class,
188: login.ControlStyle.CssClass);
189: }
190:
191: foreach (string key in login.Style.Keys) {
192: writer.AddStyleAttribute(key, login.Style[key]);
193: }
194: }
195:
196: writer.RenderBeginTag(HtmlTextWriterTag.Div);
197: }
198:
199: /// <summary>
200: /// Renders the inner contents of the <see cref="Login"/> control.
201: /// </summary>
202: /// <param name="writer">
203: /// The <see cref="HtmlTextWriter"/> object to use to output the
204: /// control's contents.
205: /// </param>
206: protected override void RenderContents(HtmlTextWriter writer) {
207: container.RenderControl(writer);
208: }
209:
210: /// <summary>
211: /// Renders the closing outer tag for the <see cref="Login"/> control.
212: /// </summary>
213: /// <param name="writer">
214: /// The <see cref="HtmlTextWriter"/> object to use to output the
215: /// control's contents.
216: /// </param>
217: protected override void RenderEndTag(HtmlTextWriter writer) {
218: writer.RenderEndTag();
219: }
220:
221: /// <summary>
222: /// Authenticates the user using the ASP.NET membership provider.
223: /// </summary>
224: /// <param name="sender">The <see cref="Login"/> control.</param>
225: /// <param name="e">The event arguments.</param>
226: private void login_Authenticate(object sender, AuthenticateEventArgs e) {
227: Login login = sender as Login;
228: Debug.Assert(login != null, "login != null");
229:
230: MembershipProvider provider;
231: string providerName = login.MembershipProvider;
232: if (!String.IsNullOrEmpty(providerName)) {
233: provider = Membership.Providers[providerName];
234: } else {
235: provider = Membership.Provider;
236: }
237:
238: e.Authenticated = provider.ValidateUser(userNameValue,
239: passwordValue);
240: }
241:
242: /// <summary>
243: /// Displays the failure text in the <see cref="Login"/> control's
244: /// output if a login error occurred.
245: /// </summary>
246: /// <param name="sender">The <see cref="Login"/> control.</param>
247: /// <param name="e">The event arguments.</param>
248: private void login_LoginError(object sender, EventArgs e) {
249: Login login = Control as Login;
250: Debug.Assert(login != null, "login != null");
251:
252: ITextControl failureText = container.FindControl("FailureText") as
253: ITextControl;
254: Debug.Assert(failureText != null, "failureText != null");
255: failureText.Text = login.FailureText;
256:
257: Control parent = ((Control)failureText).Parent;
258: if (!parent.Visible) {
259: parent.Visible = true;
260: }
261: }
262:
263: /// <summary>
264: /// Called when the value in the password text box has been changed.
265: /// </summary>
266: /// <param name="sender">
267: /// The <see cref="IEditableTextControl"/> object.
268: /// </param>
269: /// <param name="e">The event arguments.</param>
270: private void Password_TextChanged(object sender, EventArgs e) {
271: IEditableTextControl password = sender as IEditableTextControl;
272: Debug.Assert(password != null, "password != null");
273: passwordValue = password.Text;
274: }
275:
276: /// <summary>
277: /// Called when the check box status for the remember me check box
278: /// has been changed.
279: /// </summary>
280: /// <param name="sender">
281: /// The <see cref="ICheckBoxControl"/> object.
282: /// </param>
283: /// <param name="e">The event arguments.</param>
284: private void RememberMe_CheckedChanged(object sender, EventArgs e) {
285: ICheckBoxControl rememberMe = sender as ICheckBoxControl;
286: Debug.Assert(rememberMe != null, "rememberMe != null");
287: rememberMeValue = rememberMe.Checked;
288:
289: Login login = Control as Login;
290: Debug.Assert(login != null, "login != null");
291: login.RememberMeSet = rememberMeValue;
292: }
293:
294: /// <summary>
295: /// Called when the value in the user name text box has been changed.
296: /// </summary>
297: /// <param name="sender">
298: /// The <see cref="IEditableTextControl"/> object.
299: /// </param>
300: /// <param name="e">The event arguments.</param>
301: private void UserName_TextChanged(object sender, EventArgs e) {
302: IEditableTextControl userName = sender as IEditableTextControl;
303: Debug.Assert(userName != null, "userName != null");
304: userNameValue = userName.Text;
305: }
306:
307: /// <summary>
308: /// Implements the default template for the <see cref="Login"/> control.
309: /// </summary>
310: private class DefaultLoginTemplate : ITemplate {
311: /// <summary>
312: /// The <see cref="Login"/> control that the template is a template
313: /// for.
314: /// </summary>
315: private Login login;
316:
317: /// <summary>
318: /// Constructs a new <see cref="DefaultLoginTemplate"/> object.
319: /// </summary>
320: /// <param name="login">
321: /// The <see cref="Login"/> control that the template is a template
322: /// for.
323: /// </param>
324: public DefaultLoginTemplate(Login login) {
325: this.login = login;
326: }
327:
328: /// <summary>
329: /// Adds the standard <see cref="Login"/> controls to the template
330: /// container.
331: /// </summary>
332: /// <param name="container">
333: /// The parent container that the controls will be added to as
334: /// children.
335: /// </param>
336: public void InstantiateIn(Control container) {
337: CreateTitleControl(container);
338: CreateInstructionControl(container);
339: CreateFailureControl(container);
340: CreateUserInformationFieldSet(container);
341: CreateOptionsFieldSet(container);
342: CreateLoginButton(container);
343: CreateLinks(container);
344: }
345:
346: /// <summary>
347: /// Creates the controls used to render the link to create a new
348: /// user account.
349: /// </summary>
350: /// <param name="hasCreateUserIconUrl">
351: /// True if the icon should be rendered.
352: /// </param>
353: /// <param name="hasCreateUserText">
354: /// True if the link text should be rendered.
355: /// </param>
356: /// <returns>The link.</returns>
357: private Control CreateCreateUserLink(bool hasCreateUserIconUrl,
358: bool hasCreateUserText) {
359: var listItem = new HtmlGenericControl("LI") {
360: EnableViewState = false
361: };
362:
363: var link = new HyperLink() {
364: EnableViewState = false,
365: NavigateUrl = login.CreateUserUrl
366: };
367: link.MergeStyle(login.HyperLinkStyle);
368: listItem.Controls.Add(link);
369:
370: if (hasCreateUserIconUrl) {
371: var image = new Image() {
372: EnableViewState = false,
373: ImageUrl = login.CreateUserIconUrl
374: };
375: link.Controls.Add(image);
376: }
377: if (hasCreateUserText) {
378: var text = new Literal() {
379: Text = login.CreateUserText
380: };
381: link.Controls.Add(text);
382: }
383:
384: return listItem;
385: }
386:
387: /// <summary>
388: /// Creates the controls that are used to render the failure message
389: /// for the <see cref="Login"/> control.
390: /// </summary>
391: /// <param name="container">
392: /// The parent container <see cref="Control"/> that the new control
393: /// is to be added to.
394: /// </param>
395: private void CreateFailureControl(Control container) {
396: var failureTextDiv = new HtmlGenericControl("DIV") {
397: EnableViewState = false,
398: Visible = false
399: };
400: SetCssStyles(failureTextDiv, login.FailureTextStyle);
401: container.Controls.Add(failureTextDiv);
402:
403: var failureText = new Literal {
404: EnableViewState = false,
405: ID = "FailureText"
406: };
407: failureTextDiv.Controls.Add(failureText);
408: }
409:
410: /// <summary>
411: /// Creates the controls used to render the link to navigate to a
412: /// help page for the login form.
413: /// </summary>
414: /// <param name="hasCreateUserIconUrl">
415: /// True if the icon should be rendered.
416: /// </param>
417: /// <param name="hasCreateUserText">
418: /// True if the link text should be rendered.
419: /// </param>
420: /// <returns>The link.</returns>
421: private Control CreateHelpPageLink(bool hasHelpPageIconUrl,
422: bool hasHelpPageText) {
423: var listItem = new HtmlGenericControl("LI") {
424: EnableViewState = false
425: };
426:
427: var link = new HyperLink() {
428: EnableViewState = false,
429: NavigateUrl = login.HelpPageUrl
430: };
431: link.MergeStyle(login.HyperLinkStyle);
432: listItem.Controls.Add(link);
433:
434: if (hasHelpPageIconUrl) {
435: var image = new Image() {
436: EnableViewState = false,
437: ImageUrl = login.HelpPageIconUrl
438: };
439: link.Controls.Add(image);
440: }
441: if (hasHelpPageText) {
442: var text = new Literal() {
443: Text = login.HelpPageText
444: };
445: link.Controls.Add(text);
446: }
447:
448: return listItem;
449: }
450:
451: /// <summary>
452: /// Creates the controls that are used to render the instructions
453: /// for the <see cref="Login"/> control.
454: /// </summary>
455: /// <param name="container">
456: /// The parent container <see cref="Control"/> that the new control
457: /// is to be added to.
458: /// </param>
459: private void CreateInstructionControl(Control container) {
460: var instructions = new HtmlGenericControl("DIV") {
461: EnableViewState = false,
462: InnerHtml = login.InstructionText
463: };
464: SetCssStyles(instructions, login.InstructionTextStyle);
465: container.Controls.Add(instructions);
466: }
467:
468: /// <summary>
469: /// Creates the controls used to render helpful links to other pages.
470: /// </summary>
471: /// <param name="container">
472: /// The parent container <see cref="Control"/> that the new control
473: /// is to be added to.
474: /// </param>
475: private void CreateLinks(Control container) {
476: bool hasCreateUserIconUrl =
477: !String.IsNullOrEmpty(login.CreateUserIconUrl);
478: bool hasCreateUserText =
479: !String.IsNullOrEmpty(login.CreateUserText);
480: bool hasCreateUserLink = hasCreateUserIconUrl || hasCreateUserText;
481: bool hasPasswordRecoveryIconUrl =
482: !String.IsNullOrEmpty(login.PasswordRecoveryIconUrl);
483: bool hasPasswordRecoveryText =
484: !String.IsNullOrEmpty(login.PasswordRecoveryText);
485: bool hasPasswordRecoveryLink = hasPasswordRecoveryIconUrl ||
486: hasPasswordRecoveryText;
487: bool hasHelpPageIconUrl =
488: !String.IsNullOrEmpty(login.HelpPageIconUrl);
489: bool hasHelpPageText = !String.IsNullOrEmpty(login.HelpPageText);
490: bool hasHelpLink = hasHelpPageIconUrl || hasHelpPageText;
491: if (hasCreateUserLink || hasPasswordRecoveryLink || hasHelpLink) {
492: var linkList = new HtmlGenericControl("UL") {
493: EnableViewState = false
494: };
495: container.Controls.Add(linkList);
496:
497: if (hasCreateUserLink) {
498: linkList.Controls.Add(CreateCreateUserLink(
499: hasCreateUserIconUrl, hasCreateUserText));
500: }
501: if (hasPasswordRecoveryLink) {
502: linkList.Controls.Add(CreatePasswordRecoveryLink(
503: hasPasswordRecoveryIconUrl, hasPasswordRecoveryText));
504: }
505: if (hasHelpLink) {
506: linkList.Controls.Add(CreateHelpPageLink(
507: hasHelpPageIconUrl, hasHelpPageText));
508: }
509: }
510: }
511:
512: /// <summary>
513: /// Creates the <see cref="Button"/> control used to initiate the
514: /// login process.
515: /// </summary>
516: /// <param name="container">
517: /// The parent container <see cref="Control"/> that the new control
518: /// is to be added to.
519: /// </param>
520: private void CreateLoginButton(Control container) {
521: var loginButton = new Button {
522: CommandName = "Login",
523: EnableViewState = false,
524: ID = "LoginButton",
525: Text = login.LoginButtonText,
526: ValidationGroup = login.ID
527: };
528: container.Controls.Add(loginButton);
529: }
530:
531: /// <summary>
532: /// Creates the controls that are used to render the
533: /// <FIELDSET> containing authentication options.
534: /// </summary>
535: /// <param name="container">
536: /// The parent container <see cref="Control"/> that the new control
537: /// is to be added to.
538: /// </param>
539: private void CreateOptionsFieldSet(Control container) {
540: var rememberMeFieldSet = new HtmlGenericControl("FIELDSET") {
541: EnableViewState = false,
542: ID = "RememberMeFieldSet"
543: };
544: container.Controls.Add(rememberMeFieldSet);
545:
546: HtmlGenericControl rememberMeLegend =
547: new HtmlGenericControl("LEGEND") {
548: EnableViewState = false,
549: InnerText = "Options"
550: };
551: rememberMeFieldSet.Controls.Add(rememberMeLegend);
552:
553: var rememberMe = new CheckBox {
554: EnableViewState = false,
555: ID = "RememberMe",
556: Text = login.RememberMeText
557: };
558: rememberMe.MergeStyle(login.CheckBoxStyle);
559: rememberMeFieldSet.Controls.Add(rememberMe);
560: }
561:
562: /// <summary>
563: /// Creates the controls used to capture the user's password.
564: /// </summary>
565: /// <param name="container">
566: /// The container <see cref="Control"/> that the password controls
567: /// will be added to.
568: /// </param>
569: private void CreatePasswordControls(Control container) {
570: var passwordLabel = new Label {
571: AssociatedControlID = "Password",
572: EnableViewState = false,
573: ID = "PasswordLabel",
574: Text = login.PasswordLabelText
575: };
576: passwordLabel.MergeStyle(login.LabelStyle);
577: container.Controls.Add(passwordLabel);
578:
579: var password = new TextBox {
580: ID = "Password",
581: TextMode = TextBoxMode.Password
582: };
583: password.MergeStyle(login.TextBoxStyle);
584: container.Controls.Add(password);
585:
586: var passwordValidator = new RequiredFieldValidator {
587: ControlToValidate = "Password",
588: EnableViewState = false,
589: ID = "PasswordRequired",
590: Text = login.PasswordRequiredErrorMessage,
591: ToolTip = login.PasswordRequiredErrorMessage,
592: ValidationGroup = login.ID
593: };
594: passwordValidator.MergeStyle(login.ValidatorTextStyle);
595: container.Controls.Add(passwordValidator);
596: }
597:
598: /// <summary>
599: /// Creates the controls used to render the link to recover a
600: /// lost password.
601: /// </summary>
602: /// <param name="hasCreateUserIconUrl">
603: /// True if the icon should be rendered.
604: /// </param>
605: /// <param name="hasCreateUserText">
606: /// True if the link text should be rendered.
607: /// </param>
608: /// <returns>The link.</returns>
609: private Control CreatePasswordRecoveryLink(
610: bool hasPasswordRecoveryIconUrl, bool hasPasswordRecoveryText) {
611: var listItem = new HtmlGenericControl("LI") {
612: EnableViewState = false
613: };
614:
615: var link = new HyperLink() {
616: EnableViewState = false,
617: NavigateUrl = login.PasswordRecoveryUrl
618: };
619: link.MergeStyle(login.HyperLinkStyle);
620: listItem.Controls.Add(link);
621:
622: if (hasPasswordRecoveryIconUrl) {
623: var image = new Image() {
624: EnableViewState = false,
625: ImageUrl = login.PasswordRecoveryIconUrl
626: };
627: link.Controls.Add(image);
628: }
629: if (hasPasswordRecoveryText) {
630: var text = new Literal() {
631: Text = login.PasswordRecoveryText
632: };
633: link.Controls.Add(text);
634: }
635:
636: return listItem;
637: }
638:
639: /// <summary>
640: /// Creates the controls that are used to render the title of the
641: /// <see cref="Login"/> control.
642: /// </summary>
643: /// <param name="container">
644: /// The parent container <see cref="Control"/> that the new control
645: /// is to be added to.
646: /// </param>
647: private void CreateTitleControl(Control container) {
648: var title = new HtmlGenericControl("H1") {
649: EnableViewState = false,
650: InnerText = login.TitleText
651: };
652: SetCssStyles(title, login.TitleTextStyle);
653: container.Controls.Add(title);
654: }
655:
656: /// <summary>
657: /// Creates the controls that are used to render the user information
658: /// field set for the <see cref="Login"/> control.
659: /// </summary>
660: /// <param name="container">
661: /// The parent container <see cref="Control"/> that the new control
662: /// is to be added to.
663: /// </param>
664: private void CreateUserInformationFieldSet(Control container) {
665: var userInformationFieldSet =
666: new HtmlGenericControl("FIELDSET") {
667: EnableViewState = false,
668: ID = "UserInformationFieldSet"
669: };
670: container.Controls.Add(userInformationFieldSet);
671:
672: var userInformationLegend =
673: new HtmlGenericControl("LEGEND") {
674: EnableViewState = false,
675: InnerText = "User account information"
676: };
677: userInformationFieldSet.Controls.Add(userInformationLegend);
678:
679: CreateUserNameControls(userInformationFieldSet);
680: CreatePasswordControls(userInformationFieldSet);
681: }
682:
683: /// <summary>
684: /// Creates the controls used to capture the user's account name.
685: /// </summary>
686: /// <param name="container">
687: /// The container <see cref="Control"/> that the user name controls
688: /// will be added to.
689: /// </param>
690: private void CreateUserNameControls(Control container) {
691: var userNameLabel = new Label {
692: AssociatedControlID = "UserName",
693: EnableViewState = false,
694: ID = "UserNameLabel",
695: Text = login.UserNameLabelText
696: };
697: userNameLabel.MergeStyle(login.LabelStyle);
698: container.Controls.Add(userNameLabel);
699:
700: var userName = new TextBox {
701: ID = "UserName"
702: };
703: userName.MergeStyle(login.TextBoxStyle);
704: container.Controls.Add(userName);
705:
706: var userNameValidator = new RequiredFieldValidator {
707: ControlToValidate = "UserName",
708: EnableViewState = false,
709: ID = "UserNameRequired",
710: Text = login.UserNameRequiredErrorMessage,
711: ToolTip = login.UserNameRequiredErrorMessage,
712: ValidationGroup = login.ID
713: };
714: userNameValidator.MergeStyle(login.ValidatorTextStyle);
715: container.Controls.Add(userNameValidator);
716: }
717:
718: /// <summary>
719: /// Sets the CSS class name and CSS styles for a
720: /// <see cref="HtmlControl"/>.
721: /// </summary>
722: /// <param name="control">
723: /// The <see cref="HtmlControl"/> control.
724: /// </param>
725: /// <param name="style">
726: /// A <see cref="Style"/> object containing the CSS settings for
727: /// the control.
728: /// </param>
729: private void SetCssStyles(HtmlControl control, Style style) {
730: if (!style.IsEmpty) {
731: if (!String.IsNullOrEmpty(style.CssClass)) {
732: control.Attributes.Add("class", style.CssClass);
733: }
734:
735: var styles = style.GetStyleAttributes(login.Page);
736: foreach (string key in styles.Keys) {
737: control.Style.Add(key, styles[key]);
738: }
739: }
740: }
741: }
742: }