Xamarin Public Jenkins (auto-signing) e79aa3c0ed Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
2016-08-03 10:59:49 +00:00

227 lines
9.2 KiB
C#

//------------------------------------------------------------------------------
// <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