|
|
|
 |
 |
Исходник |
 |
|
 |
 |
|
Автор:
|
|
|
Название:
|
ColorDropDownList |
|
Дата:
|
29 July 2004 |
|
Описание: |
ColorDropDownList - элемент управления (выпадающий список),
дающий возможность выбрать цвет из списка. Позволяет:
1. Задать список цветов, откуда будет производиться выбор (свойство Palette):
а) из enumeration System.Drawing.KnownColor;
б) из 216 Web-safe цветов;
в) из указанных произвольных цветов для списка с помощью свойства UserDefinedColors (см. ниже, п.2).
2. Задать список определенных пользователем цветов (свойство UserDefinedColors) во время настройки контрола в design-time. В этом случае цвета будут сохранены VS.Net-дизайнером как дочерние html-елементы родительского серверного тега и считаны в run-time для занесения в выпадающий список, из которого будет производиться выбор.
3. Указать, как цвета будут показаны (свойство DisplayColorMode) - как фон для каждой опции списка, как цвет текста каждой опции или просто как техт опции).
Для удобства все классы контрола помещены в один файл.
Enjoy!
|
| |
Разместить ссылку на этот исходник в форуме вы можете вставив в текст сообщения
следующую строку:
[CODEPOST ID=106]ColorDropDownList[/CODEPOST] |
| Оценка: |
Проголосовало 7 посетителей, средняя оценка 4.29 |
| Оценить: |
|
1 using System;
2 using System.Web.UI;
3 using System.Web.UI.WebControls;
4 using System.Web.UI.Design;
5 using System.ComponentModel;
6 using System.ComponentModel.Design;
7 using System.Collections;
8 using System.Collections.Specialized;
9 using System.Drawing;
10 using System.IO;
11
12 namespace CustomWebControls
13 {
14
15 #region Enumerations
16
17 /// <summary>
18 /// The Palettes enumeration indicates which possible color sets can be displayed in
19 /// the drop-down list:
20 /// * KnownColors - all colors from the System.Drawing.KnownColor enumeration;
21 /// * WebSafeColors - the 216 colors considered as "web-safe";
22 /// these ones use only hex values #FF, #CC, #99, #66, #33 and #00 for each of
23 /// the red, green and blue components;
24 /// * UserDefinedColors - colors set by the user through the UserDefinedColors property
25 /// at design time.
26 /// </summary>
27 public enum Palettes {KnownColors=0, WebSafeColors, UserDefinedColors};
28
29 /// <summary>
30 /// The DisplayColorModes enumeration indicates how colors will be displayed in the list:
31 /// * ColorAsBackground - displays each item using its color for the background;
32 /// foreground text (color name) is displayed in white;
33 /// * ColorAsForeground - displays each item using its color for the foreground text;
34 /// * PlainText - does not display colors in the items, lists color names only.
35 /// </summary>
36 public enum DisplayColorModes {ColorAsBackground=0, ColorAsForeground, PlainText};
37
38 #endregion
39
40 [ToolboxData("<{0}:ColorDropDownList runat=server></{0}:ColorDropDownList>")
41 ,ParseChildren(false)
42 ,PersistChildren(false)
43 ,DefaultProperty("SelectedColor")
44 ,DefaultEvent("ColorChanged")
45 ,Designer(typeof(UserDefinedColorsControlDesigner))
46 ,ControlBuilder(typeof(UserDefinedColorsControlBuilder))
47 ]
48 public class ColorDropDownList : System.Web.UI.WebControls.WebControl,
49 IPostBackEventHandler, IPostBackDataHandler, INamingContainer
50 {
51 #region Private declarations
52
53 // the current set of colors
54 private Palettes palette = Palettes.KnownColors;
55 // how to display the colors
56 private DisplayColorModes displayColorMode = DisplayColorModes.ColorAsBackground;
57 // currently selected color
58 private Color selectedColor = Color.Empty;
59 // custom user prompt
60 private string prompt = "Select a color:";
61
62 // internal DropDownList control used to sub-class some properties
63 private DropDownList ddlColorsList = new DropDownList();
64 // the collection of user-defined colors
65 private ColorCollection userDefinedColors = null;
66
67 private static readonly object EventColorChanged = new object();
68
69 #endregion
70
71 #region Control properties
72
73 [Bindable(true),
74 Description("The color set to enumerate."),
75 DefaultValue(typeof(Palettes), "KnownColors"), Category("Misc")]
76 public Palettes Palette
77 {
78 get { return palette; }
79 set
80 {
81 this.EnsureChildControls();
82 palette = value;
83 }
84 }
85
86 [Bindable(true),
87 Description("Enumeration describing how the colors should be displayed (background/foreground/plain text."),
88 DefaultValue(typeof(DisplayColorModes), "ColorAsBackground"),
89 Category("Misc")]
90 public DisplayColorModes DisplayColorMode
91 {
92 get { return displayColorMode; }
93 set
94 {
95 this.EnsureChildControls();
96 displayColorMode = value;
97 }
98 }
99
100 [Bindable(true),
101 Description("Gets or sets the currently selected color from the list."),
102 DefaultValue(typeof(Color), "Color.Empty"), Category("Misc")]
103 public Color SelectedColor
104 {
105 get { return selectedColor; }
106 set
107 {
108 this.EnsureChildControls();
109 selectedColor = value;
110 }
111 }
112
113 [Description("Gets the currently selected color name."),
114 Browsable(false)]
115 public string SelectedColorName
116 {
117 get { return SelectedColor.Name; }
118 }
119
120 private string SelectedValue
121 {
122 get { return ddlColorsList.SelectedValue; }
123 set { ddlColorsList.SelectedValue = value; }
124 }
125
126 private ListItemCollection Items
127 {
128 get { return ddlColorsList.Items; }
129 }
130
131 private int SelectedIndex
132 {
133 get { return ddlColorsList.SelectedIndex; }
134 set { ddlColorsList.SelectedIndex = value; }
135 }
136
137 /// <summary>
138 /// The custom prompt to be displayed at the top of the list.
139 /// </summary>
140 [Bindable(true),
141 Description("Custom prompt to be displayed at the top of the list."),
142 DefaultValue("Select a color:"),
143 Category("Misc")]
144 public string Prompt
145 {
146 get { return prompt; }
147 set { prompt = value; }
148 }
149
150 [Bindable(true)
151 ,Description("List of user-defined colors.")
152 ,DefaultValue(typeof(ColorCollection), null)
153 ,NotifyParentProperty(true)
154 ,PersistenceMode(PersistenceMode.InnerProperty)
155 ,DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
156 ,Editor(typeof(System.ComponentModel.Design.CollectionEditor),
157 typeof(System.Drawing.Design.UITypeEditor))
158 ]
159 public ColorCollection UserDefinedColors
160 {
161 get
162 {
163 if (userDefinedColors == null)
164 userDefinedColors = new ColorCollection();
165 return userDefinedColors;
166 }
167
168 set { userDefinedColors = value; }
169 }
170
171 [Description("Automatically postback to the server after selection is changed."),
172 DefaultValue(typeof(bool), "false"),
173 Category("Behavior")]
174 public bool AutoPostBack
175 {
176 get { return ddlColorsList.AutoPostBack; }
177 set
178 {
179 this.EnsureChildControls();
180 ddlColorsList.AutoPostBack = value;
181 }
182 }
183
184 [Description("CSS Class name applied to the control."),
185 Category("Appearance"),
186 DefaultValue("")]
187 public override string CssClass
188 {
189 get
190 {
191 this.EnsureChildControls();
192 return ddlColorsList.CssClass;
193 }
194 set
195 {
196 this.EnsureChildControls();
197 ddlColorsList.CssClass = value;
198 }
199 }
200
201 #endregion
202
203 #region Event declarations
204
205 [Description("Raised when the current color has been changed."),
206 Category("Misc")]
207 public event EventHandler ColorChanged
208 {
209 add { Events.AddHandler(EventColorChanged, value); }
210 remove { Events.RemoveHandler(EventColorChanged, value); }
211 }
212
213 // Invokes delegates registered with the ColorChanged event.
214 protected virtual void OnColorChanged(EventArgs e)
215 {
216 EventHandler colorChangedHandler = (EventHandler) Events[EventColorChanged];
217 if (colorChangedHandler != null)
218 {
219 colorChangedHandler(this, e);
220 }
221 }
222
223 #endregion
224
225 #region IPostBackDataHandler members
226
227 /// <summary>
228 /// Loads the posted back data.
229 /// </summary>
230 bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection values)
231 {
232 //Page.RegisterRequiresRaiseEvent(this);
233
234 string presentValue = this.SelectedValue; // previous value
235 string postedValue = values[postDataKey]; // new value
236 if (!presentValue.Equals(postedValue))
237 {
238 this.SelectedValue = postedValue;
239 this.SelectedColor = Color.FromName(postedValue);
240 return true;
241 }
242
243 return false;
244 }
245
246 void IPostBackDataHandler.RaisePostDataChangedEvent()
247 {
248 }
249
250 #endregion
251
252 #region IPostBackEventHandler members
253
254 /// <summary>
255 /// Raises the postback events.
256 /// </summary>
257 void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
258 {
259 if (eventArgument == "ColorChanged")
260 OnColorChanged(EventArgs.Empty);
261 }
262
263 #endregion
264
265 #region Overriden methods
266
267 /// <summary>
268 /// Adds the ddlColorsList child control to the list of children.
269 /// </summary>
270 protected override void CreateChildControls()
271 {
272 this.Controls.Clear();
273 this.Controls.Add(ddlColorsList);
274 }
275
276 /// <summary>
277 /// Replaces the default SPAN opening tag for the parent Html element
278 /// with the SELECT tag.
279 /// </summary>
280 protected override HtmlTextWriterTag TagKey
281 {
282 get { return HtmlTextWriterTag.Select; }
283 }
284
285 /// <summary>
286 /// Here we merge the "color" style attribute into already existing style for
287 /// the SELECT tag - trying to avoid verbose duplication of this "color"
288 /// attribute for each child OPTION of the current SELECT tag.
289 /// </summary>
290 /// <param name="writer">The HtmlTextWriter instance to write out to.</param>
291 public override void RenderBeginTag(HtmlTextWriter writer)
292 {
293 Style myStyle = new Style();
294 switch (this.DisplayColorMode)
295 {
296 case DisplayColorModes.ColorAsBackground:
297 case DisplayColorModes.ColorAsForeground:
298 myStyle.ForeColor = System.Drawing.Color.White;
299 break;
300 case DisplayColorModes.PlainText:
301 myStyle.ForeColor = System.Drawing.Color.Black;
302 break;
303 }
304
305 base.MergeStyle(myStyle);
306
307 base.RenderBeginTag(writer);
308 }
309
310 /// <summary>
311 /// Adds the attributes we need to the parent SELECT tag.
312 /// </summary>
313 /// <param name="writer">The HtmlTextWriter instance to write out to.</param>
314 protected override void AddAttributesToRender(HtmlTextWriter writer)
315 {
316 base.AddAttributesToRender(writer);
317 writer.AddAttribute("name", this.ClientID);
318
319 if (this.AutoPostBack)
320 {
321 writer.AddAttribute("onchange", "javascript:" +
322 Page.GetPostBackEventReference(this, "ColorChanged"));
323 writer.AddAttribute("language", "javascript");
324 }
325 }
326
327 /// <summary>
328 /// Renders the content of the parent SELECT element - the collection of
329 /// OPTION Html elements.
330 /// </summary>
331 /// <param name="writer">The HtmlTextWriter instance to write out to.</param>
332 protected override void RenderContents(HtmlTextWriter writer)
333 {
334 this.PopulateColorsList();
335 this.SetColor(this.SelectedColor);
336
337 for(int iNum=0; iNum < this.Items.Count; iNum++)
338 {
339 ListItem item = this.Items[iNum];
340 writer.WriteBeginTag("option");
341 writer.WriteAttribute("value", item.Value);
342
343 // write out the style attributes
344 if (item.Attributes.Keys.Count > 0)
345 {
346 string styleValue = GetStyleAttributeValue(item.Attributes);
347 writer.WriteAttribute("style", styleValue);
348 }
349
350 if (this.SelectedValue == item.Value)
351 writer.Write(" SELECTED");
352
353 writer.Write(HtmlTextWriter.TagRightChar);
354 writer.Write(item.Text);
355 writer.WriteEndTag("option");
356 writer.WriteLine();
357 }
358 }
359
360 /// <summary>
361 /// Overriding this method of the Control class assists the
362 /// ColorDropDownList control to build the list of user-defined
363 /// colors (UserDefinedColors property).
364 /// The source Html content looks like this:
365 /// <custom:ColorDropDownList id="colorList1" runat="server" AutoPostBack="True">
366 /// <custom:ColorItem Value="Red" />
367 /// <custom:ColorItem Value="Lime" />
368 /// <custom:ColorItem Value="Blue" />
369 /// </custom:ColorDropDownList>
370 /// </summary>
371 /// <param name="obj">The object to evaluate.</param>
372 protected override void AddParsedSubObject(object obj)
373 {
374 // recognize it as a child used-defined color item in format:
375 // <custom:ColorItem Value="xxx" />
376 if (obj is ColorItem)
377 {
378 ColorItem item = obj as ColorItem;
379 this.UserDefinedColors.Add(item.Value);
380 }
381 else
382 base.AddParsedSubObject(obj);
383 }
384
385 /// <summary>
386 /// Helper function - returns color in hex format (like #C0C000).
387 /// </summary>
388 /// <param name="color">The color to be converted to hex string.</param>
389 /// <returns>The color in hex string format.</returns>
390 public static string ColorToHexString(Color color)
391 {
392 return string.Format("#{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
393 }
394
395 #endregion
396
397 #region Private/Protected methods
398
399 /// <summary>
400 /// Builds the style attribute string for the current ListItem of the control.
401 /// </summary>
402 /// <param name="attributes">The AttributeCollection object -
403 /// attributes to enumerate.</param>
404 /// <returns>The formatted style attribute string.</returns>
405 /// <exception cref="ArgumentNullException">Thrown if attributes is null.</exception>
406 private string GetStyleAttributeValue(System.Web.UI.AttributeCollection attributes)
407 {
408 if (attributes == null)
409 throw new ArgumentNullException("attributes");
410
411 string result = string.Empty;
412
413 // enumerate the style attributes
414 IEnumerator enumerator = attributes.Keys.GetEnumerator();
415 while(enumerator.MoveNext())
416 {
417 string attribName = (string) enumerator.Current;
418 string attribValue = attributes[attribName];
419
420 result += string.Format("{0}: {1}; ", attribName, attribValue);
421 }
422
423 if (result != string.Empty)
424 result = result.Substring(0, result.Length - 2);
425
426 return result;
427 }
428
429 /// <summary>
430 /// Sets the color with given name as the currently selected
431 /// color in the list.
432 /// </summary>
433 /// <param name="color">The color to find in the list.</param>
434 protected void SetColor(Color color)
435 {
436 string colorName = color.Name;
437 ListItem item = new ListItem(colorName, colorName);
438 int index = this.Items.IndexOf(item);
439
440 if (index != -1)
441 this.SelectedIndex = index;
442 }
443
444 /// <summary>
445 /// Adds the content to the custom color drop-down control -
446 /// the list of colors to choose from.
447 /// </summary>
448 private void PopulateColorsList()
449 {
450 // add the prompt item first
451 ListItem promptItem = new ListItem(this.Prompt, "Empty");
452 promptItem.Attributes.Add("color", "black");
453 this.Items.Add(promptItem);
454
455 // next, build the list of appropriate colors
456 string[] colors = this.GetColorNames();
457 ListItem[] items = this.EnumerateColors(colors);
458
459 // now, add all the color items
460 if (items != null)
461 this.Items.AddRange(items);
462 }
463
464 /// <summary>
465 /// Builds the list of color names which will be shown in the control.
466 /// </summary>
467 /// <returns>The array of strings representing color names (for named colors)
468 /// or their hex equivalents (for unnamed colors).</returns>
469 private string[] GetColorNames()
470 {
471 string[] colors = null; // return value
472 switch(this.Palette)
473 {
474 case Palettes.KnownColors:
475 colors = Enum.GetNames(typeof(System.Drawing.KnownColor));
476 break;
477 case Palettes.WebSafeColors:
478 colors = this.GetWebSafeColors();
479 break;
480 case Palettes.UserDefinedColors:
481
482 ArrayList list = new ArrayList();
483 foreach(Color color in this.UserDefinedColors)
484 {
485 string colorName = (color.IsKnownColor)? color.Name :
486 ColorToHexString(color);
487 list.Add(colorName);
488 }
489
490 colors = (string[]) list.ToArray(typeof(string));
491 break;
492 }
493
494 return colors;
495 }
496
497 /// <summary>
498 /// Returns the list of Web-safe colors (216 items);
499 /// these ones use only hex values #00, #33, #66, #99, #CC, #FF
500 /// for each of the red, green and blue components.
501 /// </summary>
502 /// <returns>The array of strings representing color values
503 /// in hex format.</returns>
504 private string[] GetWebSafeColors()
505 {
506 string[] result = null; // return value
507 string[] hexValues = new string[] {"00", "33", "66", "99", "CC", "FF"};
508
509 ArrayList list = new ArrayList();
510
511 for(int r=0; r < hexValues.Length; r++)
512 for(int g=0; g < hexValues.Length; g++)
513 for(int b=0; b < hexValues.Length; b++)
514 {
515 string color = string.Format("#{0}{1}{2}", hexValues[r], hexValues[g],
516 hexValues[b]);
517 list.Add(color);
518 }
519
520 result = (string[]) list.ToArray(typeof(string));
521 return result;
522 }
523
524 /// <summary>
525 /// Enumerates the passed string array of color names and returns the array of
526 /// ListItem objects to be used in the drop-down list of colors.
527 /// </summary>
528 /// <param name="colors">The string array of color names to enumerate.</param>
529 /// <returns>The array of ListItem objects.</returns>
530 private ListItem[] EnumerateColors(string[] colors)
531 {
532 if (colors == null) return null; // no color names to enumerate
533
534 ListItem[] items = null; // return value
535 ArrayList list = new ArrayList();
536
537 foreach(string color in colors)
538 {
539 ListItem item = new ListItem(color, color);
540
541 // format the style attributes for each item in the list
542 switch(this.DisplayColorMode)
543 {
544 case DisplayColorModes.ColorAsBackground:
545 item.Attributes.Add("background-color", color);
546 break;
547 case DisplayColorModes.ColorAsForeground:
548 item.Attributes.Add("color", color);
549 break;
550 case DisplayColorModes.PlainText: // do nothing
551 break;
552 }
553
554 list.Add(item);
555 }
556
557 items = (ListItem[]) list.ToArray(typeof(ListItem));
558
559 return items;
560 }
561
562 #endregion
563 }
564
565 #region ColorItem class
566
567 /// <summary>
568 /// Helper class used by the UserDefinedColorsControlBuilder class
569 /// to parse the inner content of the ColorDropDownList Web control.
570 /// </summary>
571 public class ColorItem
572 {
573 private string _value = string.Empty;
574
575 /// <summary>
576 /// Color name (for named colors) or its hex equivalent
577 /// (for unnamed colors).
578 /// </summary>
579 public string Value
580 {
581 get { return _value; }
582 set { _value = value; }
583 }
584
585 /// <summary>
586 /// Default constructor.
587 /// </summary>
588 public ColorItem()
589 {
590 }
591
592 public ColorItem(string _value)
593 {
594 this.Value = _value;
595 }
596 }
597
598 #endregion
599
600 #region ColorCollection class
601
602 /// <summary>
603 /// Helper class - presents the collection of colors. Used by the
604 /// UserDefinedColorsControlDesigner class to maintain the list
605 /// of user-defined colors.
606 /// </summary>
607 public class ColorCollection : CollectionBase
608 {
609 /// <summary>
610 /// Default contructor.
611 /// </summary>
612 public ColorCollection()
613 {
614 }
615
616 public ColorCollection(string[] colors) : base()
617 {
618 foreach (string s in colors)
619 this.Add(s);
620 }
621
622 public Color this[int index]
623 {
624 get { return (Color) List[index]; }
625 set { List[index] = value; }
626 }
627
628 public int Add(Color value)
629 {
630 return(List.Add(value));
631 }
632
633 public int IndexOf(Color value)
634 {
635 return(List.IndexOf(value));
636 }
637
638 public void Insert(int index, Color value)
639 {
640 List.Insert(index, value);
641 }
642
643 public void Remove(Color value)
644 {
645 List.Remove(value);
646 }
647
648 /// <summary>
649 /// Checks if the value is in the list.
650 /// </summary>
651 /// <param name="value">The value to check.</param>
652 /// <returns>True if value is in the list.</returns>
653 /// <remarks>If value is not of type Color, this will return false.</remarks>
654 public bool Contains(Color value)
655 {
656 return(List.Contains(value));
657 }
658
659 protected override void OnInsert(int index, object value)
660 {
661 base.OnInsert(index, value);
662 }
663
664 /// <summary>
665 /// Adds a color represented by the string to the collection of colors.
666 /// </summary>
667 /// <param name="value">The color string to be added.</param>
668 /// <returns>The new element position in the list.</returns>
669 /// <exception cref="ArgumentException">Thrown if the value cannot
670 /// be converted from the given string to a valid color.</exception>
671 public int Add(string value)
672 {
673 try
674 {
675 Color c = ColorTranslator.FromHtml(value);
676 return(List.Add(c));
677 }
678 catch (Exception)
679 {
680 throw new ArgumentException(
681 string.Format("Error converting string '{0}' to a color.", value));
682 }
683 }
684 }
685
686 #endregion
687
688 #region UserDefinedColorsControlDesigner class
689
690 /// <summary>
691 /// Persists the UserDefinedColors as inner Html tags like:
692 /// ...
693 /// <custom:ColorItem Value="Red" />
694 /// <custom:ColorItem Value="Green" />
695 /// <custom:ColorItem Value="Blue" />
696 /// ...
697 /// </summary>
698 public class UserDefinedColorsControlDesigner : System.Web.UI.Design.ControlDesigner
699 {
700 /// <summary>
701 /// Returns the Html string representing the UserDefinedColors to be stored
702 /// as inner html content.
703 /// </summary>
704 /// <returns>The representation of inner elements as Html string.</returns>
705 public override string GetPersistInnerHtml()
706 {
707 StringWriter sw = new StringWriter();
708 HtmlTextWriter writer = new HtmlTextWriter(sw);
709
710 ColorDropDownList combo = this.Component as ColorDropDownList;
711 if (combo != null)
712 {
713 foreach(Color color in combo.UserDefinedColors)
714 {
715 string colorName = (color.IsKnownColor ? color.Name :
716 ColorDropDownList.ColorToHexString(color));
717
718 writer.WriteBeginTag("custom:ColorItem");
719 writer.WriteAttribute("Value", colorName);
720 writer.Write(HtmlTextWriter.SelfClosingTagEnd);
721 }
722 }
723
724 return sw.ToString();
725 }
726 }
727
728 #endregion
729
730 #region UserDefinedColorsControlBuilder class
731
732 /// <summary>
733 /// When ColorDropDownList control is instantiated, its UserDefinedColors
734 /// property is populated with colors retrieved from the server tag's
735 /// inner content which looks something like:
736 /// <custom:ColorDropDownList id="colorList1" runat="server">
737 /// <custom:ColorItem Value="Red" />
738 /// <custom:ColorItem Value="Lime" />
739 /// <custom:ColorItem Value="Blue" />
740 /// </custom:ColorDropDownList>
741 /// This class assists the ColorDropDownList class (which
742 /// overrides the AddParsedSubObject method for this purpose)
743 /// to deserialize those user-defined colors
744 /// (<custom:ColorItem Value="xxx" /> tags).
745 /// The third class involved in this process: ColorItem.
746 /// </summary>
747 public class UserDefinedColorsControlBuilder : System.Web.UI.ControlBuilder
748 {
749 /// <summary>
750 /// Used to provide custom parsing of color Html elements within
751 /// the ColorDropDownList control (which define user-defined colors).
752 /// </summary>
753 public override Type GetChildControlType(string tagName, IDictionary attribs)
754 {
755 if (string.Compare(tagName,"custom:ColorItem", true) == 0)
756 {
757 return typeof(ColorItem);
758 }
759
760 return base.GetChildControlType(tagName, attribs);
761 }
762 }
763
764 #endregion
765 }
766
767 |
| Вернуться к списку исходников в категории Создание элементов управления |
|
|
 |
 |
 |
 |
|
|