datagrid将项添加到数据源丢失viewstate

时间:2009-07-17 14:00:53

标签: c# asp.net c#-3.0 datasource

我的页面有一个TextBox,一个Button和一个Datagrid。

这里的目标很简单:每次我在TextBox中输入内容并按下Button时,它会进行一些检查,然后将项目添加到datagrid和业务逻辑数据源。

问题是,如果我想让项目出现在DataGrid中,我必须做一个datagrid.DataSource = myBusinessObject; datagrid.DataBind();这个问题是我失去了用户已完成的视频状态和放射线框中的选择。

这是模板:

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

背后的代码:

    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;
        }

现在,Test1对象只是一个用于映射业务逻辑字段的小类。

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; }
}

所以我想直接的问题是:如何将项目添加到网格&amp;业务对象而不会丢失网格中放射线框的选择。

2 个答案:

答案 0 :(得分:2)

在添加新项目列表之前,您必须在业务对象中保存radiobox的状态,这样当您再次绑定它时,选项将反映在数据网格 如果你这样做,你也可以禁用网格的ViewState ......

答案 1 :(得分:0)

您的 DataGrid RadioButton 绑定到 Test1 的属性,因此如果您相应地设置它们,那么它是否应该保留所选择的选项。< / p>

我不是ASP .NET的人,我希望比我更聪明的人帮助你,但是因为没有人回答。我会试一试。您的单选按钮绑定到 Test1.IsRegister 属性,这意味着要保持其状态,您必须将该属性设置为true或false。首先更改您的Test1类以保持bool而不是字符串。现在我将CanRegister设置为true,您可以稍后更改逻辑。

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; } }
    }

现在您需要在每次有人按下 RadioButton 时保存,您需要创建一个事件处理程序并将 AutoPostBack 设置为true。

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

现在事件处理程序 register_checked 。您可以在此处获取 RadioButton.Checked 属性的值,并将其设置为列表中的项目。

 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;
                }
            }

        }

您必须完成所有这些操作的原因是因为 RadioButton ItemTemplate 的一部分,并且绑定到 DataGrid ,这意味着可能存在许多 DataGridItem ,因此许多 RadioButton 具有相同的id“register”。这就是为什么你无法从代码隐藏中获得它。

这将保留 RadioButton 的状态。希望这会对你有所帮助。