views:

646

answers:

2

I do have a page that has a TextBox a Button and a Datagrid.

The goal here is simple : Each time I input something in the TextBox and press the Button, it does a little check and then it adds the item to the datagrid and a business logic datasource.

The problem is, if I want to make the item appear in the DataGrid I have to do a datagrid.DataSource = myBusinessObject; datagrid.DataBind(); problem with that is I lose the viewstate and the choice in the radiobox the user have done.

Here is the Template :

   <asp:TextBox ID="txtDomain" runat="server" style="margin-bottom: 0px" 
    Width="254px"></asp:TextBox>
    &nbsp;<asp:Button ID="domainAdd" runat="server" onclick="domainAdd_Click" 
    style="height: 26px" Text="Ajouter" />
   &nbsp;<br />
   <br />
   <asp:DataGrid ID="dg1" runat="server" AutoGenerateColumns="false">
    <Columns>
     <asp:BoundColumn DataField="Name" HeaderText="Nom choisi"></asp:BoundColumn>
     <asp:TemplateColumn HeaderText="Enregistrer">
      <ItemTemplate>
       <asp:RadioButton ID="register" runat="server" GroupName="domaine_action" Checked='<%# Bind("IsRegister")%>' Enabled='<%# Bind("CanRegister")%>' />
      </ItemTemplate>
     </asp:TemplateColumn>
     <asp:TemplateColumn HeaderText="Transférer">
      <ItemTemplate>
       <asp:RadioButton ID="transfert" runat="server" GroupName="domaine_action" Checked='<%# Bind("IsTransfert")%>' Enabled='<%# Bind("CanTransfert")%>' />
      </ItemTemplate>
     </asp:TemplateColumn>
     <asp:TemplateColumn HeaderText="Gérer moi même">
      <ItemTemplate>
       <asp:RadioButton ID="manage" runat="server" GroupName="domaine_action" Checked='<%# Bind("IsSelfManaged")%>' Enabled='<%# Bind("CanSelfManage")%>' />
      </ItemTemplate>
     </asp:TemplateColumn>
    </Columns>
   </asp:DataGrid>

The code behind :

 protected void domainAdd_Click(object sender, EventArgs e)
 {
  if (Session["dic"] != null)
  {
   var _dic = (List<Test1>)Session["dic"];

   _dic.Add(new Test1 { Name = txtDomain.Text });

   dg1.DataSource = _dic;
   dg1.DataBind();

   Session["dic"] = _dic;
  }
  else
  {
   List<Test1> _dic = new List<Test1>();

   _dic.Add(new Test1 { Name = txtDomain.Text });

   dg1.DataSource = _dic;
   dg1.DataBind();

   Session["dic"] = _dic;
  }

For now the Test1 object is just a little class to map fields for business logic.

public class Test1
{
 public string Name { get; set; }

 public string IsRegister { get; set; }
 public string IsTransfert { get; set; }
 public string IsSelfManaged { get; set; }

 public string CanRegister { get; set; }
 public string CanTransfert { get; set; }
 public string CanSelfManage { get; set; }
}

So I guess the direct question would be : How to add items to the grid & the business object without loosing the choices of radioboxes in the grid.

A: 

Your DataGrid binds its RadioButton to properties of Test1, so if you set those accordingly, should it not keep the selected choice.

I am not an ASP .NET guy and I hope someone smarter than me helps you, but since nobody is answering. I'll give it a shot. Your radio buttons are bound to your Test1.IsRegister property, which means to keep their state you have to set that property to true or false. First change your Test1 class to hold bool's instead of strings. For now I set CanRegister to always true, you can change the logic later.

public class Test1
    {
        public string Name { get; set; }

        public bool IsRegister { get; set; }
        public bool IsTransfert { get; set; }
        public bool IsSelfManaged { get; set; }

        public bool CanRegister { get { return true; } }
        public bool CanTransfert { get { return true; } }
        public bool CanSelfManage { get { return true; } }
    }

Now you need to save each time someone presses on a RadioButton, you need to create an event handler and set AutoPostBack to true.

<asp:RadioButton OnCheckedChanged="register_checked" AutoPostBack="true" ID="register" runat="server" GroupName="domaine_action" Checked='<%# Bind("IsRegister")%>' Enabled='<%# Bind("CanRegister")%>' />

Now the event handler register_checked. This is the part where you take the value of the RadioButton.Checked property and set it to the item in your List.

 protected void register_checked(object sender, EventArgs e)
        {
            //make sure you have a list
            if(Session["dic"] == null)
                return;

            List<Test1> _dic =  (List<Test1>)Session["dic"];
            RadioButton btn = sender as RadioButton;
            string btnClientId = btn.ClientID;

            //make sure cast didnt crash
            if (btn == null)
                return;

            foreach (DataGridItem control in dg1.Items)
            {
                //find the register RadioButton, ID="register"
                var item = control.FindControl("register");
                //make sure its the right RadioButton
                if (item.ClientID.Equals(btnClientId))
                {
                    //get the item index of this DataGridItem and take the appropriate object for List<Test1>
                    Test1 realItem = _dic[control.ItemIndex] as Test1;
                    if (realItem == null)
                        continue;

                    //set the Items IsRegister to the button value.
                    realItem.IsRegister = btn.Checked;
                }
            }

        }

The reason you have to do all of this is because your RadioButtons are part of an ItemTemplate and are bound to a DataGrid, which means that potentially there will be many DataGridItems and hence many RadioButtons with the same id "register". This is why you can not get to it from the code-behind.

This will preserve the state of the RadioButtons. Hope this helps you.

Stan R.
+2  A: 

You're going to have to save the state of the radioboxes in your business object before adding a new item the List, so that when you bind it again, the choices will be reflected back in the datagrid.
If you're doing that, you might as well disable the ViewState for the grid...

Julien Poulin
yep works this way =Dnot exactly clean but works definetly :)
Erick