Как реализовать выделение полной строки в GridView без кнопки выбора?
Я реализую функцию, когда пользователь нажимает на любую точку строки в GridView, строка выбирается вместо кнопки "Выбрать".
Чтобы реализовать это, я использую следующий код:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Set the hand mouse cursor for the selected row.
e.Row.Attributes.Add("OnMouseOver", "this.style.cursor = 'hand';");
// The seelctButton exists for ensuring the selection functionality
// and bind it with the appropriate event hanlder.
LinkButton selectButton = new LinkButton()
{
CommandName = "Select",
Text = e.Row.Cells[0].Text
};
e.Row.Cells[0].Controls.Add(selectButton);
e.Row.Attributes["OnClick"] =
Page.ClientScript.GetPostBackClientHyperlink(selectButton, "");
}
}
С кодом выше, есть следующие проблемы:
- Это работает нормально, только если я
EnableEventValidation
для страницы установлено значениеfalse
, SelectedIndexChanged
увольняют только на тот случай, еслиGrid.DataBind()
называется вPage_Load
для страницы (в каждом постбеке).
Я делаю что-то неправильно? Есть ли лучшая реализация?
Изменить: когда EnableEventValidation
установлен в true
появится следующая ошибка:
Неверный аргумент обратной передачи или обратного вызова. Проверка события включена с использованием в конфигурации или <% @ Page EnableEventValidation = "true"%> на странице. В целях безопасности эта функция проверяет, что аргументы для событий обратной передачи или обратного вызова исходят от серверного элемента управления, который первоначально их представил. Если данные действительны и ожидаемы, используйте метод ClientScriptManager.RegisterForEventValidation, чтобы зарегистрировать данные обратной передачи или обратного вызова для проверки.
5 ответов
Вы должны добавлять это при каждой обратной передаче, а не только при привязке данных. Поэтому вам следует использовать RowCreated-Event объекта GridView.
Например
(С #):
protected void GridView1_RowCreated(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) {
e.Row.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
e.Row.ToolTip = "Click to select row";
e.Row.Attributes["onclick"] = this.Page.ClientScript.GetPostBackClientHyperlink(this.GridView1, "Select$" + e.Row.RowIndex);
}
}
(VB.Net):
Private Sub GridView1_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowCreated
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Attributes("onmouseover") = "this.style.cursor='pointer';this.style.textDecoration='underline';"
e.Row.Attributes("onmouseout") = "this.style.textDecoration='none';"
e.Row.ToolTip = "Click to select row"
e.Row.Attributes("onclick") = Me.Page.ClientScript.GetPostBackClientHyperlink(Me.GridView1, "Select$" & e.Row.RowIndex)
End If
End Sub
Вместо того, чтобы делать это на RowCreated
Вы могли бы сделать это на Render()
, Таким образом, вы можете использовать перегрузку GetPostBackClientHyperlink
с истинным на registerForEventValidation
и избежать ошибки "неверный аргумент обратного вызова / обратного вызова".
Что-то вроде этого:
protected override void Render(HtmlTextWriter writer)
{
foreach (GridViewRow r in GridView1.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
r.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
r.Attributes["onmouseout"] = "this.style.textDecoration='none';";
r.ToolTip = "Click to select row";
r.Attributes["onclick"] = this.Page.ClientScript.GetPostBackClientHyperlink(this.GridView1, "Select$" + r.RowIndex,true);
}
}
base.Render(writer);
}
<style type="text/css">
.hiddenColumn
{
display: none;
}
.rowGrid
{
cursor: pointer;
}
</style>
<asp:GridView runat="server" ID="GridView1" AutoGenerateColumns="true" >
<RowStyle CssClass="rowGrid" />
<Columns>
<asp:CommandField ButtonType="Button" ShowSelectButton="true" HeaderStyle-CssClass="hiddenColumn"
ItemStyle-CssClass="hiddenColumn" FooterStyle-CssClass="hiddenColumn" />
</Columns>
</asp:GridView>
<script type="text/javascript">
$(function () {
$("#<%= GridView1.ClientID %> tr.rowGrid")
.live("click", function (event) {
$(this).find("input[type='button'][value='Select']").click();
});
$("#<%= GridView1.ClientID %> input[type='button'][value='Select']")
.live("click", function (event) {
event.stopPropagation();
});
});
</script>
Попробуйте добавить событие OnSelectedIndexChanged в сетку
OnSelectedIndexChanged="Grid_SelectedIndexChanged"
а затем на код позади
protected void Grid_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = gvSummary.SelectedRow;
//Int32 myvalue= Convert.ToInt32(row.Attributes["ColumnName"].ToString());
}
и установите EnableViewState="false", но здесь вам нужно выполнить еще две вещи, которые вы уже сделали в своем коде, означает установить для EnableEventValidation значение false и привязку к сетке на странице Load..
Попробуйте использовать <asp:LinkButton>
вокруг вашего <tr>
в коде ASPX установите LinkButton's CommandName='Select'
А в элементе команды item обработайте эту команду и задайте стиль выбранной строки!