トップ回答者
DataListのradioButtonをグループ化したい

質問
-
のですがどうしたらいいのでしょうか。とりあえず下記の様なソースでradioButtonの右隣にロゴをつけてみました。
<asp
ataList ID="DataList1" runat="server" RepeatColumns="7" RepeatDirection="horizontal">
<ItemTemplate>
<asp:RadioButton ID="RadioButton1" runat="server" GroupName="iconGroup" /><img src='<%# DataBinder.Eval(Container.DataItem, "iconName")%>' alt='<%# DataBinder.Eval(Container.DataItem, "iconType") %>' />
</ItemTemplate>
</aspataList>
しかし、このままではグループ化していないので、全部セレクトされてしまいます。いろいろ調べているのですが・・・。
回答
-
ラジオボタンのグループ化ですよね。
RadioButton.GroupName プロパティで設定可能ですよ。
[RadioButton.GroupName プロパティ ]
http://msdn2.microsoft.com/ja-jp/library/system.web.ui.webcontrols.radiobutton.groupname(VS.80).aspx
-
おかしいですね? 参照の追加でOverItemRadioを含むプロジェクトを追加されましたでしょうか? もしそうであれば、ツールボックスからドラッグ&ドロップして下さい。このようにした時は、
<%@ Register Assembly="hoge" Namespace="fuga"
TagPrefix="cc1" %>
のようなディレクティブが自動的に追加されますので、web.configをいじる必要はありません。
通常はツールボックスからドラッグ&ドロップすると思いますので、web.configで設定せず、@Registerディレクティブにより、各Webページで設定する方がいいかもしれません。
すべての返信
-
ラジオボタンのグループ化ですよね。
RadioButton.GroupName プロパティで設定可能ですよ。
[RadioButton.GroupName プロパティ ]
http://msdn2.microsoft.com/ja-jp/library/system.web.ui.webcontrols.radiobutton.groupname(VS.80).aspx
-
その後、調べていますと、GroupNameは変わりませんが、UniqueIDとClientIDが変わっています。DataList1$ctl00$RadioButton1になっていました。しかし、依然として複数選択されてしまいます。加えたコードは下記です。
DataList1.DataSource = dTable;
DataList1.DataBind();int count = DataList1.Items.Count;
for (int i = 0; i < count; i++)
{
RadioButton radio = (RadioButton)DataList1.Items.FindControl("RadioButton1");
if (i == 0)
{
radio.Checked = true;
}
//radio.GroupName = "iconGroup";
//radio.ID = "RadioButton1";
string test = radio.GroupName;
string test2 = radio.UniqueID;
}これで、初期設定で最初のボタンにcheckする事は出来ました。
あるサイトではこの問題はmicrosoftも解決していない様な事が書いてあり、まさかそんな事はないと思うんですがどうでしょうか。
その他、RadioButtonListを使う方法も調べているのですが、この状況にはあまり当てはまらないような気がします。これで試したのですが、<asp:ListItem>に<img src = '<%# DataBinder.Eval(Container.DataItem, "iconName")....%>とdatabindは出来ないメッセージが出ました。
-
KentaroM さんからの引用 その後、調べていますと、GroupNameは変わりませんが、UniqueIDとClientIDが変わっています。DataList1$ctl00$RadioButton1になっていました。しかし、依然として複数選択されてしまいます。
RadioButtonのName属性が、GroupNameやUniqueIDを組み合わせて生成されてしまうため、複数選択可能になっているようです。
解決するには以下のようにRadioButtonを継承して新しいWebコントロールを作り、例えばGroupNameからのみなる同一のName属性を生成するようにすれば可能です。
Gridview and RadioButton
http://forums.asp.net/thread/921771.aspxもしくは、RadioButtonをクリックする度にポストバックが発生しますが、コードで全てのRadioButtonのチェックをクリアして、クリックされたRadioButtonのみチェックするということもできると思います。ただ、あまり効率はよくないですね。(^^;
-
結構面倒くさいんですね。それで、radiobuttonの継承がいまいちわからないのですが、下記のコードを現行のコードに継承する事は出来るのでしょうか?
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.IO;namespace Nishizaki.Web.UI
{
public class OverItemRadio: RadioButton
{
protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
bool result = base.LoadPostData(postDataKey, postCollection);
bool newChecked = postCollection[GroupName] == this.UniqueID;
if (this.Checked != newChecked)
{
this.Checked = newChecked;
return true;
}
return result;
}protected override void Render(HtmlTextWriter writer)
{
base.Render(new WriterWrapper(writer, this));
}private class WriterWrapper : HtmlTextWriter
{
private OverItemRadio control;public WriterWrapper(TextWriter writer, OverItemRadio control)
: base(writer)
{
this.control = control;
}public override void AddAttribute(HtmlTextWriterAttribute key, string value)
{
switch (key)
{
case HtmlTextWriterAttribute.Name:
base.AddAttribute(key, control.GroupName);
break;
case HtmlTextWriterAttribute.Value:
base.AddAttribute(key, control.UniqueID);
break;
default:
base.AddAttribute(key, value);
break;
}
}
}
}
}現行のコード
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;using System.Data.Common;
using System.Text;
using System.IO;
using System.Collections.Specialized;public partial class PostReply : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ConnectionStringSettings setting = ConfigurationManager.ConnectionStrings["db2ConnectionString"];
DbProviderFactory factory = DbProviderFactories.GetFactory(setting.ProviderName);DbConnection conn = factory.CreateConnection();
conn.ConnectionString = setting.ConnectionString;
conn.Open();DbCommand comm = factory.CreateCommand();
comm.Connection = conn;
comm.CommandText = "Select iconName, iconType from icon";DbDataAdapter adapter = factory.CreateDataAdapter();
adapter.SelectCommand = comm;
DataSet dSet = new DataSet();
adapter.Fill(dSet, "icon");DataTable dTable = dSet.Tables["icon"];
DataList1.DataSource = dTable;
DataList1.DataBind();int count = DataList1.Items.Count;
for (int i = 0; i < count; i++)
{
// HtmlInputRadioButton radio1 = (HtmlInputRadioButton)DataList1.Items.FindControl("Radio1");
RadioButton radio = (RadioButton)DataList1.Items.FindControl("RadioButton1");
if (i == 0)
{
radio.Checked = true;
}
}
}protected void DataListDataBound(object sender, DataListItemEventArgs e)
{//DataRow row = ((DataRowView)e.Item.DataItem).Row;
//RadioButton radio = (RadioButton)e.Item.FindControl("RadioButton1");
//radio.GroupName = "iconGroup";
}
}aspxページ
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="PostReply.aspx.cs" Inherits="PostReply" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>無題のページ</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table style="width: 90%;">
<tr>
<td colspan="2" style="background-color3E3E3E; color:White; font-family:Verdana;">Post a Reply:</td>
</tr>
<tr>
<td style="font-family:Verdana;">
Displayed Name:</td>
<td width = "70%">
<aspataList ID="DataList1" runat="server" RepeatColumns="7" RepeatDirection="horizontal" OnItemDataBound="DataListDataBound">
<ItemTemplate>
<asp:RadioButton ID="RadioButton1" GroupName="iconName" runat="server" Checked="false"/>
<asp:Image ID="Image1" runat="server" ImageUrl='<%# DataBinder.Eval(Container.DataItem, "iconName")%>' AlternateText='<%# DataBinder.Eval(Container.DataItem, "iconType") %>' />
</ItemTemplate>
</aspataList></td>
</tr>
<tr>
<td >
</td>
<td >
<asp:RadioButton ID="RadioButton2" runat="server" GroupName="group" />
<asp:RadioButton ID="RadioButton3" runat="server" GroupName="group" /></td>
</tr>
<tr>
<td >
</td>
<td >
</td>
</tr>
</table>
</div>
</form>
</body>
</html>よろしくお願いします。
-
KentaroM さんからの引用
それで、radiobuttonの継承がいまいちわからないのですが、下記のコードを現行のコードに継承する事は出来るのでしょうか?
いえ、そういう意味の継承ではありません。RadioButtonを継承して作成したOverItemRadioというWebコントロールを、現行のコードで使うだけです。データバインドコントロール内で使用できるカスタムラジオボタンの作成
http://codezine.jp/a/article/aid/840.aspx?p=2をご覧になっているのでしょうか? Nishizaki.Web.UIからにしざきさんだと思って探しました。さすがですね。
Webカスタムコントロールは別プロジェクトにした方が良いでしょう。プロジェクトからWebコントロールライブラリをテンプレートとして選択して下さい。(なぜかWindowsのカテゴリ内にありますが)
このプロジェクトを今のソリューションで右クリックして追加して下さい。それからソリューションを右クリックして参照の追加を選び、プロジェクトタブで、追加したプロジェクトを選択してOKボタンを押します。
次にweb.configに以下のように追加します。
<system.web>
<pages>
<controls>
<add tagPrefix="hoge"
namespace="fuga"
assembly="OverItemRadio" >
</add>
</controls>
</pages>
</system.web>#web.configではなく、各ページに次のように書く事もできます。
<%@ Register Assembly="OverItemRadio" Namespace="fuga" TagPrefix="hoge" %>
そうしておいて、以下のように使います。<ItemTemplate>
<hogeverItemRadio id="RadioButton1" runat="server" GroupName="iconName" /></B>
</ItemTemplate> -
webCustomColtrolは見つけました。これを開くと下記のコードがデフォルトで入っていますが、
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;namespace WebControlLibrary1
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]
public class WebCustomControl1 : WebControl
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
String s = (String)ViewState["Text"];
return ((s == null) ? String.Empty : s);
}set
{
ViewState["Text"] = value;
}
}protected override void RenderContents(HtmlTextWriter output)
{
output.Write(Text);
}
}
}これを例のにしざきさんのコードを追加するのでしょうか?それとも入れ替えるのでしょうか?
-
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;using System.Collections.Specialized;
namespace fuga
{
[DefaultProperty("Checked")]
[ToolboxData("<{0}verItemRadio runat=server></{0}
verItemRadio>")]
public class OverItemRadio : RadioButton
{
protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
bool result = base.LoadPostData(postDataKey, postCollection);
bool newChecked = postCollection[GroupName] == this.UniqueID;
if (this.Checked != newChecked)
{
this.Checked = newChecked;
return true;
}
return result;
}protected override void Render(HtmlTextWriter writer)
{
base.Render(new WriterWrapper(writer, this));
}private class WriterWrapper : HtmlTextWriter
{
private OverItemRadio control;public WriterWrapper(TextWriter writer, OverItemRadio control)
: base(writer)
{
this.control = control;
}public override void AddAttribute(HtmlTextWriterAttribute key, string value)
{
switch (key)
{
case HtmlTextWriterAttribute.Name:
base.AddAttribute(key, control.GroupName);
break;
case HtmlTextWriterAttribute.Value:
base.AddAttribute(key, control.UniqueID);
break;
default:
base.AddAttribute(key, value);
break;
}
}
}
}
}
で、よろしいのでしょうか。それで、web.configに
<pages>
<controls>
<add tagPrefix="hoge"
namespace="fuga"
assembly="OverItemRadio" >
</add>
</controls>
</pages>を加えてdatalistのitemtemplateに
<hoge
verItemRadio id="RadioButton17" runat="server" GroupName="iconName" />
を加えましたが、エラーです。OverItemRadioが不明なサーバータグです。と出てしまいます。
-
おかしいですね? 参照の追加でOverItemRadioを含むプロジェクトを追加されましたでしょうか? もしそうであれば、ツールボックスからドラッグ&ドロップして下さい。このようにした時は、
<%@ Register Assembly="hoge" Namespace="fuga"
TagPrefix="cc1" %>
のようなディレクティブが自動的に追加されますので、web.configをいじる必要はありません。
通常はツールボックスからドラッグ&ドロップすると思いますので、web.configで設定せず、@Registerディレクティブにより、各Webページで設定する方がいいかもしれません。