Ограничение размера текста в столбце GridView

#c# #asp.net #gridview

#c# #asp.net #gridview

Вопрос:

У меня есть asp: GridView, объявленный следующим образом:

 <asp:GridView runat="server" id="dg_myprojects" AllowSorting="true" AutoGenerateColumns="false" Width="900px" CssClass="Grid" OnSorting="TaskGridView_SortingMine" OnRowCommand="MyProjectList_RowCommand" DataKeyNames="project_id" OnRowDataBound="Ds_my_projects_RowDataBound">
    <AlternatingRowStyle CssClass="alternateRow" />
    <HeaderStyle CssClass="GridHeader" />
    <Columns>
        <asp:BoundField DataField="project_name" HeaderText="Project Name" SortExpression="project_name"/>
        <asp:BoundField DataField="description" HeaderText="Description" SortExpression="description" ItemStyle-HorizontalAlign="Left" />
        <asp:BoundField DataField="role" HeaderText="Role" SortExpression="role" />
        <asp:BoundField DataField="start_date" HeaderText="Start Date" SortExpression="start_date" DataFormatString="{0:d}"/>
        <asp:BoundField DataField="end_date" HeaderText="End Date" SortExpression="end_date" DataFormatString="{0:d}" />
        <asp:BoundField DataField="client" HeaderText="Client" SortExpression="client" />
        <asp:TemplateField>
        <ItemTemplate>
             <asp:LinkButton ID="DeleteButton" CommandArgument='<%# Eval("project_id") %>' CommandName="Remove" runat="server">Remove</asp:LinkButton>
        </ItemTemplate></asp:TemplateField>
        <asp:HyperLinkField DataNavigateUrlFields="project_id" DataNavigateUrlFormatString="EditProject.aspx?pID={0}" Text="Edit"/>
    </Columns>
</asp:GridView>
  

Моя проблема на 100% эстетична. Перенос слов, который происходит для длинных описаний, делает таблицу безвкусной. То, что я хочу сделать с длинным описанием, — это многоточие (…), когда описание становится слишком длинным

Длинное описание бла-бла…

Я не смог найти встроенный метод для этого, поэтому я решил попробовать реализовать это OnRowDataBound в GridView.

 protected void Ds_my_projects_RowDataBound(object sender, GridViewRowEventArgs e)
{            
   DataRow curRow = ((DataRowView)e.Row.DataItem).Row;
  if (curRow["Description"].ToString().Length > 200)
       curRow["Description"] = curRow["Description"].ToString().Substring(0, 200)   "...";

}
  

Я получаю исключение во время выполнения в первой строке из-за того, что ссылка на объект не установлена для экземпляра объекта.

Что я здесь делаю не так? Есть ли более простой способ выполнить то, что я пытаюсь сделать?

Комментарии:

1. Я не думаю, что для этого есть какой-либо встроенный метод, то, как вы это делаете, правильно.

Ответ №1:

Вы могли бы справиться с этим с помощью css и добавив это в свой Grid класс css:

 .Grid {
    table-layout:fixed; 
    width:100%; 
}
.Grid .Shorter {
    overflow: hidden; 
    text-overflow: ellipsis; 
    white-space: nowrap;        
}
  

Обновление: я изменил приведенный выше класс, чтобы вы могли влиять на отдельный столбец, используя атрибут ItemStyle-CssClass следующим образом:

 <asp:BoundField DataField="description" HeaderText="Description" 
    SortExpression="description" ItemStyle-CssClass="Shorter" />
  

Комментарии:

1. Отлично работает. К сожалению, table-layout: fixed устанавливает одинаковую ширину всех моих столбцов, но я найду обходной путь

2. Спасибо. Это отличное решение, но что, если я захочу сделать что-то, где при наведении курсора отображается весь текст?

Ответ №2:

Что я хотел бы сделать, так это создать класс расширения, который может сокращать строки. Статический класс будет иметь что-то вроде следующего метода:

 public static string Shorten(this string name, int chars)
{
    if (name.ToCharArray().Count() > chars)
    {
        return name.Substring(0, chars)   "...";
    }
    else return name;
}
  

Затем вы могли бы использовать BoundFields в качестве TemplateFields следующим образом:

 <asp:TemplateField> 
    <ItemTemplate>
        <asp:Label ID="lblDesc" Text="<%# Eval("description").ToString().Shorten(20) %>" />
    </ItemTemplate>
</asp:TemplateField>
  

Самое приятное в этом то, что теперь вы можете использовать этот Shorten() метод где угодно.

Комментарии:

1. 1 за отличное решение, которое можно применять везде, где это необходимо. Методы расширения настолько удобны, когда используются правильно!

2. runat="server" отсутствует в теге Label

Ответ №3:

У CAbbot есть отличное предложение. Я никогда не делал этого таким образом, но если это работает для вас, то мне это нравится; просто, элегантно, эффективно.

То, как я всегда это делал, проходило через источник данных. Если вы привязываете a SqlDataSource к своему GridView , вы можете выполнить запрос select следующим образом:

 DECLARE @temp NVARCHAR(255);
DECLARE @maxLength INT;
SET @temp = 'The quick brown fox jumped over the lazy dog.';
SET @maxLength = 10;

SELECT CASE WHEN LEN(@temp) > @maxLength THEN SUBSTRING(@temp, 0, @maxLength)   '...' ELSE @temp END
  

Что касается устранения проблемы с вашим RowDataBound , это тоже должно сработать. Но вам не нужно выполнять приведение, попробуйте вместо этого:

 protected void Ds_my_projects_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        if (e.Row.Cells[1].Text.ToString().Length > 200)
        {
            e.Row.Cells[1].Text = e.Row.Cells[1].Text.ToString().Substring(0, 200)   "...";
        }
    }
}
  

Комментарии:

1. Просто и эффективно. Я, вероятно, не буду менять свою процедуру, но изменение текста в rowdatabound работает для меня

Ответ №4:

Замечание столбца GridView в поле шаблона отображается как «Замечание …», а всплывающая подсказка отображается в виде полного текста.

  <ItemTemplate>    <asp:Label ID="lblRemark" runat="server" 
                   Text= '<%# Eval("Remark").ToString().Length > 6? (Eval("Remark") as string).Substring(0,6)   " ..." : Eval("Remark")  %>'
                   tooltip = '<%# Eval("Remark") %> '> </asp:Label>
 </ItemTemplate>
  

Ответ №5:

  <asp:TemplateField HeaderText="Description" SortExpression="description" >
    <ItemTemplate >
      <%# Eval("description").ToString().Length>100? (Eval("description") as string).Substring(0,100) "..." : Eval("description")  %> 
    </ItemTemplate>
 </asp:TemplateField> 
  

Ответ №6:

Я попробовал этот код, и он отлично работал. Добавьте следующий код на свою страницу .aspx :

         <asp:TemplateField HeaderText="Body" ItemStyle-Width="900px">
            <ItemTemplate >
                <%#Eval("Body").ToString().Length > 125 ? (Eval("Body").ToString().Substring(0,125)) "........": Eval("Body") %>
            </ItemTemplate>
        </asp:TemplateField>