none
DataListのradioButtonをグループ化したい RRS feed

  • 質問

  • のですがどうしたらいいのでしょうか。とりあえず下記の様なソースでradioButtonの右隣にロゴをつけてみました。

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

    しかし、このままではグループ化していないので、全部セレクトされてしまいます。いろいろ調べているのですが・・・。

    2007年5月8日 9:28

回答

  • ラジオボタンのグループ化ですよね。

    RadioButton.GroupName プロパティで設定可能ですよ。

     

    [RadioButton.GroupName プロパティ ]

    http://msdn2.microsoft.com/ja-jp/library/system.web.ui.webcontrols.radiobutton.groupname(VS.80).aspx

    2007年5月8日 9:57
  • おかしいですね? 参照の追加でOverItemRadioを含むプロジェクトを追加されましたでしょうか? もしそうであれば、ツールボックスからドラッグ&ドロップして下さい。このようにした時は、


    <%@ Register Assembly="hoge" Namespace="fuga"
        TagPrefix="cc1" %>


    のようなディレクティブが自動的に追加されますので、web.configをいじる必要はありません。
    通常はツールボックスからドラッグ&ドロップすると思いますので、web.configで設定せず、@Registerディレクティブにより、各Webページで設定する方がいいかもしれません。

    2007年5月11日 16:02
    モデレータ

すべての返信

  • ラジオボタンのグループ化ですよね。

    RadioButton.GroupName プロパティで設定可能ですよ。

     

    [RadioButton.GroupName プロパティ ]

    http://msdn2.microsoft.com/ja-jp/library/system.web.ui.webcontrols.radiobutton.groupname(VS.80).aspx

    2007年5月8日 9:57
  • その後、調べていますと、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.ItemsIdea.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は出来ないメッセージが出ました。

    2007年5月9日 5:43
  •  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のみチェックするということもできると思います。ただ、あまり効率はよくないですね。(^^;

    2007年5月10日 2:02
    モデレータ
  • 結構面倒くさいんですね。それで、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.ItemsIdea.FindControl("Radio1");
                RadioButton radio = (RadioButton)DataList1.ItemsIdea.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-color[:#]3E3E3E; color:White; font-family:Verdana;">Post a Reply:</td>
                    
                </tr>
                <tr>
                    <td style="font-family:Verdana;">
                        Displayed Name:</td>
                    <td width = "70%">
                        <aspBig SmileataList 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>
                        </aspBig SmileataList></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>

    よろしくお願いします。

     

    2007年5月10日 2:42
  •  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>
            <hogeSurpriseverItemRadio id="RadioButton1" runat="server" GroupName="iconName" /></B>
      </ItemTemplate>

    2007年5月10日 5:38
    モデレータ
  • 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);
            }
        }
    }

    これを例のにしざきさんのコードを追加するのでしょうか?それとも入れ替えるのでしょうか?

    2007年5月11日 7:06
  • WebCustomControl1 はあくまで雛形なんで、classの記述部分を全部にしざきさんのコードと入れ替えてください。DefaultPropertyはラジオボタンなんでCheckedでしょう。ToolboxDataのWebCustomControl1も、にしざきさんのコードのクラス名にして下さい。あと、WebCustomControl1.vbというファイル名も、クラス名などに適当に変えましょう。
    2007年5月11日 7:54
    モデレータ
  • 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}SurpriseverItemRadio runat=server></{0}SurpriseverItemRadio>")]
        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に

     <hogeSurpriseverItemRadio  id="RadioButton17" runat="server" GroupName="iconName" />

    を加えましたが、エラーです。OverItemRadioが不明なサーバータグです。と出てしまいます。

    2007年5月11日 8:37
  • おかしいですね? 参照の追加でOverItemRadioを含むプロジェクトを追加されましたでしょうか? もしそうであれば、ツールボックスからドラッグ&ドロップして下さい。このようにした時は、


    <%@ Register Assembly="hoge" Namespace="fuga"
        TagPrefix="cc1" %>


    のようなディレクティブが自動的に追加されますので、web.configをいじる必要はありません。
    通常はツールボックスからドラッグ&ドロップすると思いますので、web.configで設定せず、@Registerディレクティブにより、各Webページで設定する方がいいかもしれません。

    2007年5月11日 16:02
    モデレータ
  • このところ仕事が忙しくお返事できずすみませんでした。更に研究してやってみます。ありがとうございました!
    2007年5月18日 3:15