使ASP.Net GridView列固定大小并进行自动换行

时间:2013-04-11 18:45:52

标签: asp.net gridview word-wrap fixed-width

在ASP.Net Web表单中有一个GridView。我们希望在此GridView中为其中一列提供固定大小,并使其中的文本也进行自动换行。我们无法让它发挥作用。

这是我尝试过的标记:

<asp:BoundField DataField="AssignmentDetails" HeaderText="Assignment" 
    SortExpression="AssignmentDetails" ItemStyle-Width="20" ItemStyle-Wrap="true">

    <HeaderStyle HorizontalAlign="Left" />
    <ItemStyle HorizontalAlign="Left" />
</asp:BoundField>

我们认为这会使列长20个字符并使单词换行但不会那样做。

*更新*

它现在基于Darren的编码样本工作。这是GridView的完整标记和使用他的技术的代码隐藏:

        <asp:GridView
            ID="GridViewSummary" 
            runat="server" 
            AllowSorting="True" 
            AutoGenerateColumns="False" 
            DataKeyNames="ID" 
            Width="691px" 
            AllowPaging="True"
            PageSize="5"
            OnRowDataBound="GridViewSummary_RowDataBound">

            <Columns>
                <asp:BoundField DataField="AssignmentDate" HeaderText="Date" 
                    SortExpression="AssignmentDate" DataFormatString="{0:MM/dd/yyyy}">

                    <HeaderStyle HorizontalAlign="Left" />
                    <ItemStyle HorizontalAlign="Left" />
                </asp:BoundField>

                <asp:BoundField DataField="AssignmentDueDate" HeaderText="Date Due" 
                    SortExpression="AssignmentDueDate" DataFormatString="{0:MM/dd/yyyy}">

                    <HeaderStyle HorizontalAlign="Left" />
                    <ItemStyle HorizontalAlign="Left" />
                </asp:BoundField>

                <asp:BoundField DataField="Class" HeaderText="Class" 
                    SortExpression="Class">

                    <HeaderStyle HorizontalAlign="Left" />
                    <ItemStyle HorizontalAlign="Left" />
                </asp:BoundField>

                <asp:BoundField DataField="TeacherName" HeaderText="Teacher" 
                    SortExpression="TeacherName">

                    <HeaderStyle HorizontalAlign="Left" />
                    <ItemStyle HorizontalAlign="Left" />
                </asp:BoundField>

                <asp:TemplateField HeaderText="Assignment" SortExpression="AssignmentDetails">
                    <ItemTemplate>
                        <asp:Label ID="LabelAssignment" runat="server" Text='<%# Bind("AssignmentDetails") %>'></asp:Label>
                    </ItemTemplate>

                    <HeaderStyle HorizontalAlign="Left" />
                    <ItemStyle HorizontalAlign="Left" Wrap="True" />
                </asp:TemplateField>

                <asp:TemplateField ShowHeader="False">
                    <ItemTemplate>
                        <asp:Button 
                            ID="ButtonSelect" 
                            runat="server" 
                            CausesValidation="False" 
                            CommandName="Select" 
                            Text="Select Assignment Details" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

代码隐藏:

Protected Sub GridViewSummary_RowDataBound(sender As Object, e As GridViewRowEventArgs)

    ' Deal with Data type rows, and not headers etc.
    '-----------------------------------------------
    If (e.Row.RowType = DataControlRowType.DataRow) Then

        Dim lblAssignment As Label = e.Row.FindControl("LabelAssignment")

        ' Call a recursive method and insert a line break every 20 chars.
        '----------------------------------------------------------------
        lblAssignment.Text = InsertlineBreak(lblAssignment.Text)
    End If
End Sub

Function InsertlineBreak(ByVal original As String) As String

    Dim MaxStringLength As Int16 = 20

    If original.Length > MaxStringLength Then
        Dim indexOfSpace = original.IndexOf(" ", MaxStringLength - 1)
        If indexOfSpace <> -1 AndAlso indexOfSpace <> original.Length - 1 Then
            Dim firstString As String = original.Substring(0, indexOfSpace)
            Dim secondString As String = original.Substring(indexOfSpace)

            Return firstString & "<br/>" & InsertlineBreak(secondString)
        Else
            Return original
        End If
    Else
        Return original
    End If
End Function

我还将此技术应用于DetailsView以及此标记和代码隐藏中显示的内容:

                <asp:TemplateField HeaderText="Details:" SortExpression="AssignmentDetails">
                    <EditItemTemplate>
                        <asp:TextBox ID="TextBoxAssignmentDetails" runat="server" Text='<%# Bind("AssignmentDetails") %>' TextMode="MultiLine"
                            rows="5"></asp:TextBox>
                    </EditItemTemplate>

                    <InsertItemTemplate>
                        <asp:TextBox ID="TextBoxAssignmentDetails" runat="server" Text='<%# Bind("AssignmentDetails") %>' TextMode="MultiLine"
                            rows="5"></asp:TextBox>
                    </InsertItemTemplate>

                    <ItemTemplate>
                        <asp:Label 
                            ID="LabelAssignmentDetails" 
                            runat="server" 
                            Text='<%# Bind("AssignmentDetails") %> '
                            OnDataBinding="LabelAssignmentDetails_DataBinding">
                        </asp:Label>
                    </ItemTemplate>

                    <ItemStyle ForeColor="Blue" />
                </asp:TemplateField>

代码隐藏:

Protected Sub LabelAssignmentDetails_DataBinding(sender As Object, e As EventArgs)

    Dim lblAssignment As Label = DetailsView.FindControl("LabelAssignmentDetails")

    ' Call a recursive method and insert a line break every 20 chars.
    '----------------------------------------------------------------
    lblAssignment.Text = InsertlineBreak(lblAssignment.Text)
End Sub

3 个答案:

答案 0 :(得分:1)

好的,所以项目宽度不会像基于像素那样工作,而不是基于Jason所说的字符。

您需要在网格中的每一行的RowDataBound事件上处理此问题。

这个例子是在VB中,虽然将它转换为C#对你来说不会太难我确定。

在你的代码隐藏中执行类似的操作 - 将“MyGridView”替换为网格名称。

首先,将绑定字段更改为模板字段;更容易控制..并在该模板中放置一个Literal来保存您的文本,为此示例调用此MyLit

Private Sub MyGridView(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles MyGridView.RowDataBound
        '' only want to deal with Data type rows, and not headers etc
        If (e.Row.RowType = DataControlRowType.DataRow) Then

             '' get this instance of the object you're binding (assuming object is Assignment)
             Dim assignment As Assignment = CType(e.Row.DataItem, Assignment)
             '' now get the literal control where you will be putting your text
            Dim MyLit as Literal = row.FindControl("MyLit")

            '' you can now call a recursive method and insert a line break every 20 chars
            MyLit.Text = InsertlineBreak(assignment.TextToSplitUp)

        End If

End Sub


 Function InsertlineBreak(ByVal original As String) As String
        Dim MaxStringLength As Int16 = 20

        If original.Length > MaxStringLength Then
            Dim indexOfSpace = original.IndexOf(" ", MaxStringLength - 1)
            If indexOfSpace <> -1 AndAlso indexOfSpace <> original.Length - 1 Then
                Dim firstString As String = original.Substring(0, indexOfSpace)
                Dim secondString As String = original.Substring(indexOfSpace)

                Return firstString & Chr(10) & InsertlineBreak(secondString)
            Else
                Return original
            End If
        Else
            Return original
        End If
    End Function

我还没有测试过这段代码 - 我刚刚将其打破了,但它会让你知道如何继续。请不要只是复制/粘贴,然后注释它不能立即使用。需要了解更多信息,以提供一个确切的工作示例。 :)

答案 1 :(得分:1)

设置ItemStyle-CssClass="WrappedText",然后在CSS中执行:

.WrappedText
{
  word-break: break-all;
  word-wrap: break-word;
}

答案 2 :(得分:0)

ItemStyle-Width设置列的像素宽度,而不是字符数。如果内容无法以20像素包裹,则会扩展列。