1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
//------------------------------------------------------------------------------
// <copyright file="WmlRadioButtonAdapter.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if WMLSUPPORT
namespace System.Web.UI.WebControls.Adapters {
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.Web;
using System.Web.UI;
using System.Web.UI.Adapters;
using System.Web.Util;
public class WmlRadioButtonAdapter : WmlCheckBoxAdapter, IPostBackDataHandler {
private const String _groupPrefix = "__rb_";
protected new RadioButton Control {
get {
return (RadioButton)base.Control;
}
}
protected string GroupFormVariable {
get {
return _groupPrefix + Control.UniqueGroupName;
}
}
private void DetermineGroup(RadioButton r) {
if (RadioButtonGroups[r.UniqueGroupName] == null) {
RadioButtonGroups[r.UniqueGroupName] = RenderAsGroup(r);
}
}
private RadioButtonGroup GetGroupByName(string groupName) {
Debug.Assert(RadioButtonGroups.Contains(groupName), "Attemping to get group name without procesing group");
return RadioButtonGroups[groupName] as RadioButtonGroup;
}
// Returns a textual representation of a textbox.
protected override string InputElementText {
get {
return Control.Checked ? RadioButtonAdapter.AltSelectedText : RadioButtonAdapter.AltUnselectedText;
}
}
private bool IsWhiteSpace(string s) {
for (int i = 0; i < s.Length; i++) {
if (!Char.IsWhiteSpace(s, i)) return false;
}
return true;
}
private IDictionary RadioButtonGroups {
get {
if (Control.Page != null && Control.Page.Items[this.GetType()] == null) {
Control.Page.Items[this.GetType()] = new HybridDictionary();
}
return (HybridDictionary)Control.Page.Items[this.GetType()];
}
}
// Renders the control.
protected internal override void Render(HtmlTextWriter markupWriter) {
WmlTextWriter writer = (WmlTextWriter)markupWriter;
DetermineGroup(Control);
RadioButtonGroup group = GetGroupByName(Control.UniqueGroupName);
if (group != null) {
if (!group.RegisteredGroup) {
// GroupFormVariable is passed as the name & value becuase it is both the key
// for the postback data, and the WML client side var used to
// select an item in the list.
((WmlPageAdapter)PageAdapter).RegisterPostField(writer, GroupFormVariable, GroupFormVariable, true /*dynamic field*/, false /*random*/);
group.RegisteredGroup = true;
}
if (group.RenderAsGroup) {
// Render opening select if not already opened
if (!group.RenderedSelect) {
if (group.SelectedButton != null) {
((WmlPageAdapter)PageAdapter).AddFormVariable(writer, GroupFormVariable, group.SelectedButton, false /*random*/);
}
writer.WriteBeginSelect(GroupFormVariable, group.SelectedButton, null /*iname */,
null /*ivalue*/, Control.ToolTip, false /*multiple */);
if (!writer.AnalyzeMode) {
group.RenderedSelect = true;
}
}
// Render option
// We don't do autopostback if the radio button has been selected.
// This is to make it consistent that it only posts back if its
// state has been changed. Also, it avoids the problem of missing
// validation since the data changed event would not be fired if the
// selected radio button was posting back.
if (Control.AutoPostBack && !Control.Checked) {
((WmlPageAdapter)PageAdapter).RenderSelectOptionAsAutoPostBack(writer, Control.Text, Control.UniqueID);
}
else {
((WmlPageAdapter)PageAdapter).RenderSelectOption(writer, Control.Text, Control.UniqueID);
}
// Close, if list is finished
if (!writer.AnalyzeMode && --group.ButtonsInGroup == 0) {
writer.WriteEndSelect();
}
}
// must render as autopostback, radio buttons not in consecutive group.
else {
if (!Control.Enabled) {
RenderDisabled(writer);
return;
}
string iname = Control.Checked ? Control.ClientID : null;
string ivalue = Control.Checked ? "1" : null;
if (ivalue != null) {
((WmlPageAdapter)PageAdapter).AddFormVariable(writer, iname, ivalue, false /*random*/);
}
writer.WriteBeginSelect(null, null, iname, ivalue, Control.ToolTip, true /*multiple*/);
if (!Control.Checked) {
((WmlPageAdapter)PageAdapter).RenderSelectOptionAsAutoPostBack(writer, Control.Text, GroupFormVariable, Control.UniqueID);
}
else {
((WmlPageAdapter)PageAdapter).RenderSelectOption(writer, Control.Text, Control.UniqueID);
}
writer.WriteEndSelect();
}
}
}
// RenderAsGroup returns a RadioButtonGroup object if the group should be
// rendered in a single <select> statement, or null if autopostback should
// be enabled.
// UNDONE: Check more general case when radiobuttons do not all share the same parent
private RadioButtonGroup RenderAsGroup(RadioButton r) {
bool startedSequence = false;
bool finishedSequence = false;
RadioButtonGroup group = new RadioButtonGroup();
//TODO : Check all controls on page
foreach (Control c in r.Parent.Controls) {
RadioButton radioSibling = c as RadioButton;
LiteralControl literalSibling = c as LiteralControl;
if (radioSibling != null && radioSibling.UniqueGroupName == r.UniqueGroupName) {
startedSequence = true;
group.ButtonsInGroup++;
if (radioSibling.Checked == true) {
group.SelectedButton = radioSibling.UniqueID;
}
if (finishedSequence || !radioSibling.Enabled) {
group.ButtonsInGroup = -1; // can't be rendered in a group
break;
}
}
else if (startedSequence && (literalSibling == null || !IsWhiteSpace(literalSibling.Text))) {
finishedSequence = true;
}
}
return group;
}
/// <internalonly/>
// Implements IPostBackDataHandler.LoadPostData.
protected override bool LoadPostData(String key, NameValueCollection data) {
bool dataChanged = false;
string selButtonID = data[GroupFormVariable];
if (!String.IsNullOrEmpty(selButtonID)) {
// Check if this radio button is now checked
if (StringUtil.EqualsIgnoreCase(selButtonID, Control.UniqueID)) {
if (Control.Checked == false) {
Control.Checked = true;
dataChanged = true;
}
}
else {
// Don't need to check if radiobutton was
// previously checked. We only raise an event
// for the radiobutton that is selected.
// This is how a normal RadioButton behaves.
Control.Checked = false;
}
}
return dataChanged;
}
/// <internalonly/>
// Implements IPostBackDataHandler.RaisePostDataChangedEvent()
protected override void RaisePostDataChangedEvent() {
((IPostBackDataHandler)Control).RaisePostDataChangedEvent();
}
}
internal class RadioButtonGroup {
public int ButtonsInGroup;
public bool RenderedSelect;
public bool RegisteredGroup;
public String SelectedButton;
public bool RenderAsGroup {
get {
if (ButtonsInGroup < 0) {
return false;
}
return true;
}
}
}
}
#endif
|