1

GridView 内のアイテムのコンテキスト メニューに取り組んでいますが、大きな障害が 1 つあります。HTTP ハンドラーと対話してデータベースを更新する JQuery に、右クリックされた行の PK 値を送信する方法がわかりません。

基本的に、コンテキスト メニューには、[返信]、[既読にする]、[削除] の 3 つの項目があります。いずれの場合もmailid、データベースからの値を JQuery で使用できるようにする必要があります。これにより、選択したメールに返信できるページにユーザーをリダイレクトしたり、更新するデータベース内の項目を HTTP ハンドラーに通知したりできます。

これが私のコードです:

    protected void gvItems_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            e.Row.Attributes["onClick"] = "getMailDetail(" + DataBinder.Eval(e.Row.DataItem, "mailid") + ")";
            e.Row.Attributes["id"] = DataBinder.Eval(e.Row.DataItem, "mailid");

            Label lblStatus = (Label)e.Row.FindControl("lblStatus");

            if (lblStatus.Text == "unread")
            {
                e.Row.Font.Bold = true;
            }
        }
    }

行の onClick 属性を設定して、GridViewRow の任意の場所をクリックすると、ページがトリガーされてメールが詳細に表示されるようにします。別の属性を使用して、同じ方法で mailid 値を取得できると考えました。

そして.aspxで...

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="jquery.contextMenu.js"></script>
<script type="text/javascript">
    function getMailDetail(mailId) {
        $.ajax({
            type: "GET",
            url: '<%= ResolveUrl("~/GetMail.ashx") %>',
            data: { mid: mailId },
            success: function (data) {
                var pnlList = $('#<%= pnlList.ClientID %>');
                var pnlMail = $('#<%= pnlMail.ClientID %>');
                var lblFrom = $('#<%= lblFrom.ClientID %>');
                var lblDate = $('#<%= lblDate.ClientID %>');
                var lblSubject = $('#<%= lblSubject.ClientID %>');
                var lblMessage = $('#<%= lblMessage.ClientID %>');

                lblFrom.text(data.From);
                lblDate.text(data.Date);
                lblSubject.text(data.Subject);
                lblMessage.text(data.Message);

                pnlList.css("display", "none");
                pnlMail.css("display", "block");
            }
        });
    }

    function markRead(mailId) {
        $.ajax({
            type: "POST",
            url: '<%= ResolveUrl("~/MailAction.ashx") %>',
            data: { mid: mailId, act: "markRead" },
            success: window.location = "Inbox.aspx"
        });
    }

    function deleteMail(mailId) {
        $.ajax({
            type: "POST",
            url: '<%= ResolveUrl("~/MailAction.ashx") %>',
            data: { mid: mailId, act: "Delete" },
            success: window.location = "Inbox.aspx"
        });
    }
</script>
<div class="columns">
    <div class="leftcol">
        <a href="Write.aspx" class="button">Compose Message</a>

        <ul>
            <li><a href="SentItems.aspx">Sent Items</a></li>
            <li class="active"><a href="Inbox.aspx">Inbox</a></li>
            <li><a href="DeletedItems.aspx">Deleted Items</a></li>
        </ul>
    </div>

    <div class="rightcol">
        <asp:Panel runat="server" ID="pnlList">
            <div class="rightalign">
                <asp:Label runat="server" ID="lblCount"></asp:Label>
            </div>

            <asp:GridView runat="server" ID="gvItems" DataKeyNames="mailid" 
                AutoGenerateColumns="false" onrowdatabound="gvItems_RowDataBound" 
                Width="100%">
                <Columns>
                    <asp:TemplateField ItemStyle-CssClass="centeralign">
                        <HeaderTemplate>
                            <asp:CheckBox runat="server" ID="chkSelectAll" />
                        </HeaderTemplate>
                        <ItemTemplate>
                            <asp:CheckBox runat="server" ID="chkSelect" />
                        </ItemTemplate>
                    </asp:TemplateField>

                    <asp:TemplateField ItemStyle-CssClass="hidden" HeaderStyle-CssClass="hidden">
                        <ItemTemplate>
                            <asp:Label runat="server" ID="lblStatus" Text='<%# DataBinder.Eval(Container.DataItem, "status") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:BoundField ItemStyle-CssClass="hidden" HeaderStyle-CssClass="hidden" DataField="mailid" />
                    <asp:BoundField DataField="firstname" HeaderText="From" SortExpression="firstname" />
                    <asp:BoundField DataField="datesent" HeaderText="Date" SortExpression="datesent" DataFormatString="{0:yyyy/MM/dd HH:mm}" />
                    <asp:BoundField DataField="subject" HeaderText="Subject" SortExpression="subject" />
                </Columns>
            </asp:GridView>
        </asp:Panel>

        <asp:Panel runat="server" ID="pnlMail" cssclass="hidden">
            <p>From: <asp:Label runat="server" ID="lblFrom"></asp:Label><br />
                Sent On: <asp:Label runat="server" ID="lblDate"></asp:Label><br />
                Subject: <asp:Label runat="server" ID="lblSubject"></asp:Label></p>
            <p><asp:Label runat="server" ID="lblMessage"></asp:Label></p>
        </asp:Panel>
    </div>
</div>

<!-- Row Context Menu -->
<ul id="contextmenu" class="contextMenu">
    <li><a href="#reply">Reply</a></li>
    <li><a href="#mread">Mark As Read</a></li>
    <li><a href="#delete">Delete</a></li>
</ul>

<script type="text/javascript">
    $(document.ready(function() {
        $(".dataRow").contextMenu({
            menu: 'contextmenu' },
            function(action, el, pos, mid) {
                contextMenuWork(action, el, pos);
            }
        );
    },
    function contextMenuWork(action, el, pos) {
        var mid = $(el).attr("id");
        switch (action) {
            case "reply":
            {
                window.location = "Reply.aspx?id=" + mid;
                break;
            }
            case "mread":
            {
                markRead(mid);
                break;
            }
            case "delete":
            {
                deleteMail(mid);
                break;
            }
        }
    }
);
</script>

残念ながら、新しくバインドされた GridViewRow の id 属性の割り当てで InvalidCastException を取得しているため、ここでの私のアプローチには問題があるようです:

タイプ 'object' を 'string' に暗黙的に変換することはできません。明示的な変換が存在します (キャストがありませんか?)

だから、私はその行をこれに置き換えます

e.Row.Attributes["id"] = (string)DataBinder.Eval(e.Row.DataItem, "mailid");

そして今、設計時に Visual Studio から通知されるエラーはありませんが、実行時に次の InvalidCastException が発生します。

タイプ 'System.Int32' のオブジェクトをタイプ 'System.String' にキャストできません。

整数がどこから来ているのかわからないので、続行する方法がわかりません。

どんな助けでも大歓迎です。

4

1 に答える 1

0

ここで値の有効なキャストを取得できなかったので、RowDataBound void を次のように変更しました。

    protected void gvItems_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            var mailid = DataBinder.Eval(e.Row.DataItem, "mailid");
            e.Row.Attributes["onClick"] = "getMailDetail(" + DataBinder.Eval(e.Row.DataItem, "mailid") + ")";
            e.Row.Attributes["id"] = mailid.ToString();

            Label lblStatus = (Label)e.Row.FindControl("lblStatus");

            if (lblStatus.Text == "unread")
            {
                e.Row.Font.Bold = true;
            }
        }
    }

newvarを宣言し、「mailid」の DataItem 値を指定して .ToString() を指定すると、すべての問題が解決しました

于 2012-10-23T10:09:59.010 に答える