Сохранение значения CheckBox в динамическом GridView TemplateField - PullRequest
1 голос
/ 02 сентября 2011

Я пытаюсь создать GridView, который будет содержать список пользователей и уровней разрешений, к которым они имеют доступ.Каждая строка будет иметь следующие поля: User_ID, Имя пользователя, Permission1, Permission2, ..., PermissionN, где значения поля полномочий равны «0», если у пользователя нет этого разрешения, и «1», если они есть (обратите внимание, чтостолбцы, возвращаемые DAL, не называются Permission1, а являются фактическим именем разрешения).Я хотел бы представлять данные с помощью флажков, чтобы администратор мог быстро предоставить или отозвать разрешения большому количеству пользователей одновременно.

Поскольку я не буду знать количество разрешений заранее, ядинамически создавать TemplateFields и CheckBoxes, и это прекрасно работает;GridView показывает текущие уровни разрешений всех пользователей.Я сталкиваюсь с проблемой, когда пытаюсь обновить разрешения, основываясь на полях для проверки и снятия отметки с пользователя.

Как только пользователь закончит изменение разрешений, у меня есть кнопка «Обновить», которая, конечно, вызывает обратную передачу.Поскольку обратная передача происходит до события OnClick, к тому времени, когда я достигаю OnClick, все флажки будут сброшены до их начальных значений.Есть ли способ, как я могу каким-то образом получить значение свойства CheckBoxes 'Checked, прежде чем происходит обратная передача?Есть ли другой (лучший) способ сделать это?Спасибо.

ASPX:

<asp:GridView ID="gvUsers" runat="server" AutoGenerateColumns="False"
EnableModelValidation="True" DataKeyNames="ID">
</asp:GridView>
<asp:ObjectDataSource ID="odsUsers" runat="server" SelectMethod="GET_USERS"
TypeName="oDAL">
</asp:ObjectDataSource>
<asp:Button ID="btnUpdate" runat="server" Text="Update Permissions" OnClick="btnUpdate_OnClick"/>

Код сзади:

private static string[] excludeCols = { "ID", "Username" };
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack) // Removing the IsPostBack check refreshes the GridView when the Update button is clicked
        bindGridViewWithHiddenID(gvUsers, ((DataView)odsUsers.Select()).Table, excludeCols);
}

public static bool bindGridViewWithHiddenID(GridView gv, DataTable dt, string[] excludeCols)
{
    gv.Columns.Clear();
    gv.DataBind();
    if (gv != null && dt != null && dt.Rows.Count > 0)
    {
        DataControlField newField;
        foreach (DataColumn column in dt.Columns)
        {
            if (excludeCols.Contains(column.ColumnName))
            {
                newField = new BoundField();
                ((BoundField)newField).DataField = column.ColumnName;
            }
            else
            {
                newField = new TemplateField();
                ((TemplateField)newField).ItemTemplate = new CustomTemplate(column.ColumnName);
            }
            newField.HeaderText = column.ColumnName;
            if (column.ColumnName == "ID" || column.ColumnName.EndsWith("_ID"))
                newField.Visible = false;
            gv.Columns.Add(newField);
        }

        gv.DataSource = dt;
        gv.DataBind();
        return true;
    }
    return false;

}

// By this time execution reaches here the CheckBoxes have already been reset
protected void btnUpdate_Click(object sender, EventArgs e)
{
    ...
}

Класс CustomTemplate:

public class CustomTemplate : ITemplate
{
private string binding;
private static int count = 0;
public CustomTemplate(string colNameBinding)
{
    binding = colNameBinding;
}

public void InstantiateIn(Control container)
{
    CheckBox chk = new CheckBox();
    chk.ID = "chk" + count++;
    chk.DataBinding += new EventHandler(this.chk_OnDataBinding);
    container.Controls.Add(chk);
}

public void chk_OnDataBinding(object sender, EventArgs e)
{
    CheckBox chk = (CheckBox)sender;
    GridViewRow namingContainer = (GridViewRow)chk.NamingContainer;
    DataRowView dataRow = (DataRowView)namingContainer.DataItem;

    if (dataRow[binding].ToString() == "1")
        chk.Checked = true;
    else
        chk.Checked = false;
}

Ответы [ 2 ]

0 голосов
/ 02 сентября 2011

Я попытался добавить привязку GridView к OnInit (), но поскольку CheckBoxes фактически не создаются, пока GridView не станет DataBound, и поскольку DataBinding вернет GridView обратно в исходное состояние, я, похоже, снова застрял.

0 голосов
/ 02 сентября 2011

Такое поведение ожидается и является нормальным.Это связано с жизненным циклом страницы и отслеживанием ViewState для динамически добавленных элементов управления.Я рекомендую вам прочитать эту статью от Скотта Митчелла, особенно раздел под названием: Просмотр состояния и динамически добавленные элементы управления.

...