1

誰かがこれに答える前に、私は私のコードにバグを見つけ、以下に私の答えを投稿しました。私はこの質問を(誰かが本当に気にしない限り)常にあなたの自主規制音を拘束するための注意話として残しておきGridViewます。


序文/背景

私はASP.NETWebFormsコントロールを奇妙な方法で(ab)使用しています。知っている。

私は、生徒が参加した学校の活動を一覧表示することが期待されるアプリケーションに取り組んでいます。生徒は複数の行を追加できます。一般的なワークフロー上の理由からGridView、「保存された」エントリを表示するを分離することにしました。アクティビティを追加/更新する「詳細」領域から。

編集/更新部分は美しく機能します。新しいアイテムを追加したり、クラスに関連付けた組み込みの検証を使用したりできます(これは、属性spanを持つすべての追加タグがclass="error"表示するものです)。私は本当にこのばかげた証拠を作りたかったので、新しいアクティビティを追加するためにクリックするボタンは、情報を検証して追加しGridView(アイテムが検証に合格した場合)、詳細コントロールをクリアし、通常どおりに動作します。

問題の説明

これについていくつかの基本的なテストを開始しました。アクティビティを編集し、そのクラスの検証ルールの1つ(または複数)を破って、[新しいアクティビティの追加]ボタンをクリックすると、GridViewその行がEditItemTemplate後ろから通常ItemTemplate

私の知る限り、EditIndex編集中の行から外れることはありません。実際、別のポストバックをトリガーすると、GridViewが正しいことを示しますEditIndex

を再設定して、ステートメントEditIndexに切り替えました。何も機能していません。複数のポストバックを通じて値が一定に保たれていることを考えると、ここで何か奇妙なことが起こっていると考えなければなりません。e.Cancel = truereturnEditIndex's

以下にマークアップとC#コードを投稿しました。どちらもかなり長いです-私は自分の機能から地獄をリファクタリングします-それで私は前もって謝罪し、アドバイスを提供するのに十分勇敢な(または十分に退屈している)人に感謝します。

また、マークアップ/コードを読む代わりに(またはそれに加えて)誰かがこれが起こっているのを見たい場合は、スクリーンショットを提供できます。

GridView

<asp:GridView ID="schoolActivities" AutoGenerateColumns="false" runat="server">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Button ID="edit" CommandName="Edit" runat="server" Text="Edit" />
            </ItemTemplate>
            <EditItemTemplate></EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <HeaderTemplate></HeaderTemplate>
            <ItemTemplate>
                <%# DataBinder.GetPropertyValue(Container.DataItem, "Details") %>
            </ItemTemplate>
            <EditItemTemplate>Editing...</EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <HeaderTemplate>
                Months per Year
            </HeaderTemplate>
            <ItemTemplate><%# DataBinder.GetPropertyValue(Container.DataItem, "MonthsPerYear") %></ItemTemplate>
            <EditItemTemplate></EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <HeaderTemplate>Date</HeaderTemplate>
            <ItemTemplate>
                <%# DataBinder.GetPropertyValue(Container.DataItem, "ActivityDate") %>
            </ItemTemplate>
            <EditItemTemplate></EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <HeaderTemplate>
                Total Hours Outside Class Time
            </HeaderTemplate>
            <ItemTemplate>
                <%# DataBinder.GetPropertyValue(Container.DataItem, "TotalHours") %>
            </ItemTemplate>
            <EditItemTemplate></EditItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

「詳細」セクション

<br />
<button type="button" id="newActivity" runat="server">Add New Activity</button>
<br />

<fieldset id="schoolActivityFields" runat="server" visible="false">
    <legend>Activity</legend>

    <span>Details:</span>
    <span>
        <textarea id="schoolActivityDetails" class="schoolActivityDetails" runat="server"></textarea>
        <br />
        <span id="schoolActivityDetailsError" class="error" runat="server"></span>
    </span>
    <br />

    <span>Months per Year:</span>
    <span>
        <select id="schoolActivityMonthsPerYear" runat="server">
            <option>1</option>
            <option>2</option>
            <option>3</option>
            <option>4</option>
            <option>5</option>
            <option>6</option>
            <option>7</option>
            <option>8</option>
            <option>9</option>
            <option>10</option>
            <option>11</option>
            <option>12</option>
        </select>
    </span>
    <span id="schoolActivityMonthsPerYearError" class="error" runat="server"></span>
    <br />

    <span>Date:</span>
    <span>
        <select id="schoolActivityDate" runat="server">
            <option>2005</option>
            <option>2006</option>
            <option>2007</option>
            <option>2008</option>
            <option>2009</option>
            <option>2010</option>
            <option>2011</option>
            <option>2012</option>
        </select>
    </span>
    <span id="schoolActivityDateError" class="error" runat="server"></span>
    <br />

    <span>Total Hours:</span>
    <span>
        <input type="text" id="schoolActivityTotalHours" runat="server" />
    </span>
    <span id="schoolActivityTotalHoursError" class="error" runat="server"></span>
    <br />

    <button type="button" id="addActivity" runat="server">Add Activity</button>
    <button type="button" id="updateActivity" runat="server" visible="false">Update Activity</button>
    <button type="button" id="cancelEditActivity" runat="server" visible="false">Cancel Editing Activity</button>
    <button type="button" id="deleteActivity" runat="server" visible="false">Delete Activity</button>
</fieldset>

C#の長さは巨大ですが、勇敢な人には次のようになります。

void addActivity_ServerClick(object sender, EventArgs e)
{
    AddSchoolActivity();
}

private bool AddSchoolActivity()
{
    ResetSchoolActivityErrors();
    SchoolActivity activityToAdd = GetSchoolActivity();

    try
    {
        SessionApplication.SchoolActivities.Add(activityToAdd);

        BindSchoolActivities();
        ResetSchoolActivityFields();
        HideSchoolActivityFields();
    }
    catch (BrokenRuleException)
    {
        MapSchoolActivityErrors(activityToAdd);
        return false;
    }

    return true;
}

void updateActivity_ServerClick(object sender, EventArgs e)
{
    UpdateSchoolActivity();
}

private bool UpdateSchoolActivity()
{
    ResetSchoolActivityErrors();
    SchoolActivity activityToUpdate = GetSchoolActivity();

    try
    {
        SessionApplication.SchoolActivities[schoolActivities.EditIndex] = activityToUpdate;
        ResetSchoolActivitiesEditIndex();

        BindSchoolActivities();
        ResetSchoolActivityFields();
        HideSchoolActivityFields();
    }
    catch (BrokenRuleException)
    {
        MapSchoolActivityErrors(activityToUpdate);
        SetSchoolActivitiesEditIndex(schoolActivities.EditIndex);
        return false;
    }

    return true;
}

private SchoolActivity GetSchoolActivity()
{
    SchoolActivity currentActivity = new SchoolActivity();

    currentActivity.Details = schoolActivityDetails.Value;

    TryGetSchoolActivityMonthsPerYear(currentActivity);
    TryGetSchoolActivityDate(currentActivity);
    TryGetSchoolActivityTotalHours(currentActivity);

    return currentActivity;
}

private void TryGetSchoolActivityMonthsPerYear(SchoolActivity currentActivity)
{
    byte monthsPerYear;

    if (byte.TryParse(schoolActivityMonthsPerYear.Value, out monthsPerYear))
    {
        currentActivity.MonthsPerYear = monthsPerYear;
    }
}

private void TryGetSchoolActivityDate(SchoolActivity currentActivity)
{
    short activityDate = -1;

    if (short.TryParse(schoolActivityDate.Value, out activityDate))
    {
        currentActivity.ActivityDate = activityDate;
    }
}

private void TryGetSchoolActivityTotalHours(SchoolActivity currentActivity)
{
    short totalHours = -1;

    if (schoolActivityTotalHours.Value.IsNullOrWhiteSpace() == false
        && short.TryParse(schoolActivityTotalHours.Value, out totalHours))
    {
        currentActivity.TotalHours = totalHours;
    }
}

private void ResetSchoolActivityFields()
{
    schoolActivityDetails.Value = string.Empty;
    schoolActivityMonthsPerYear.SelectedIndex = 0;
    schoolActivityDate.SelectedIndex = 0;
    schoolActivityTotalHours.Value = string.Empty;
}

private void HideSchoolActivityFields()
{
    schoolActivityFields.Visible = false;
}

private void MapSchoolActivityErrors(int activityIndex)
{
    SchoolActivity updatedActivity = SessionApplication.SchoolActivities[activityIndex];

    MapSchoolActivityErrors(updatedActivity);
}

private void MapSchoolActivityErrors(SchoolActivity updatedActivity)
{
    foreach (RuleViolation currentViolation in updatedActivity.GetRuleViolations())
    {
        schoolActivityErrorMapping[currentViolation].InnerText = currentViolation.ErrorMessage;
    }
}

private void ResetSchoolActivityErrors()
{
    foreach (RuleViolation currentViolation in schoolActivityErrorMapping.Keys)
    {
        schoolActivityErrorMapping[currentViolation].InnerText = string.Empty;
    }
}

void schoolActivities_RowEditing(object sender, GridViewEditEventArgs e)
{
    if (schoolActivities.EditIndex != e.NewEditIndex
        && schoolActivities.EditIndex != -1)
    {
        ResetSchoolActivityErrors();
        SchoolActivity activityToUpdate = GetSchoolActivity();

        try
        {
            SessionApplication.SchoolActivities[schoolActivities.EditIndex] = activityToUpdate;
        }
        catch (BrokenRuleException)
        {
            MapSchoolActivityErrors(activityToUpdate);
            e.Cancel = true;
        }
    }

    if (e.NewEditIndex != -1)
    {
        SchoolActivity activityToEdit = SessionApplication.SchoolActivities[e.NewEditIndex];

        SetSchoolActivityFields(activityToEdit);
        ShowSchoolActivityFields();
        ShowModifyActivityButtons();
    }

    SetSchoolActivitiesEditIndex(e.NewEditIndex);
    BindSchoolActivities();
}

private void ShowModifyActivityButtons()
{
    addActivity.Visible = false;
    updateActivity.Visible = true;
    cancelEditActivity.Visible = true;
    deleteActivity.Visible = true;
}

private void SetSchoolActivityFields(SchoolActivity activityToEdit)
{
    schoolActivityDetails.Value = activityToEdit.Details;
    schoolActivityMonthsPerYear.Value = activityToEdit.MonthsPerYear.ToString();
    schoolActivityDate.Value = activityToEdit.ActivityDate.ToString();
    schoolActivityTotalHours.Value = activityToEdit.TotalHours.ToString();
}

private bool ShowSchoolActivityFields()
{
    return schoolActivityFields.Visible = true;
}

private void BindSchoolActivities()
{
    schoolActivities.DataSource = SessionApplication.SchoolActivities;
    schoolActivities.DataBind();
}

void newActivity_ServerClick(object sender, EventArgs e)
{
    if (SessionApplication.SchoolActivities.Count < SchoolActivityList.Rules.MaxCount)
    {
        if (schoolActivities.EditIndex != -1)
        {
            if (UpdateSchoolActivity() == false)
            {
                return;
            }
        }
        else if (schoolActivityFields.Visible)
        {
            if (AddSchoolActivity() == false)
            {
                return;
            }
        }

        ShowSchoolActivityFields();
        ShowAddActivityButtons();
    }
}

private void ShowAddActivityButtons()
{
    addActivity.Visible = true;
    updateActivity.Visible = false;
    cancelEditActivity.Visible = false;
    deleteActivity.Visible = false;
}

void ResetSchoolActivitiesEditIndex()
{
    SetSchoolActivitiesEditIndex(-1);
}

void SetSchoolActivitiesEditIndex(int rowIndex)
{
    schoolActivities.EditIndex = rowIndex;
}
4

1 に答える 1

0

はぁ。バインディング関数の呼び出しを逃しました。

UpdateSchoolActivity()次のようになります。

private bool UpdateSchoolActivity()
{
    ResetSchoolActivityErrors();
    SchoolActivity activityToUpdate = GetSchoolActivity();

    try
    {
        SessionApplication.SchoolActivities[schoolActivities.EditIndex] = activityToUpdate;
        ResetSchoolActivitiesEditIndex();

        BindSchoolActivities();
        ResetSchoolActivityFields();
        HideSchoolActivityFields();
    }
    catch (BrokenRuleException)
    {
        MapSchoolActivityErrors(activityToUpdate);
        SetSchoolActivitiesEditIndex(schoolActivities.EditIndex);
        BindSchoolActivities(); // That little guy? Don't worry about that little guy.
        return false;
    }

    return true;
}
于 2012-07-20T16:57:37.360 に答える