WPF - GridView.GridViewColumn two lines per row?

2019-07-03 07:40发布

问题:

Hello is it possible to have a ListView -> ListView.View -> GridView -> GridViewColumn with "two rows" per row.
eg.
            COLUMN 1 | COLUMN 2
ROW 1 blah          | data
            blah
ROW 2 etc            | more

I have tried unsuccessfully to use a Cell template but the item inside the template doesn't resize when its containing column is manually resized.

Code:

        <ListView Height="238" DockPanel.Dock="Top" ItemsSource="{Binding Blah}" 
              SelectedItem="{Binding Path=Selectedblah, UpdateSourceTrigger=PropertyChanged}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="No." DisplayMemberBinding="{Binding Path=Id}" Width="25" />
                <GridViewColumn Header="Job Type" DisplayMemberBinding="{Binding Path=Something}" Width="165" />
                <GridViewColumn Header="Assigned To" DisplayMemberBinding="{Binding Path=SomethingElse}" Width="90" />
                <GridViewColumn Header="Created" DisplayMemberBinding="{Binding Path=DateCreated, Converter={StaticResource dateTimeFormat}, ConverterParameter='dd/MM/yy HH:mm'}" Width="65" />
                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <Image Source="/Streetcar.UI.Modules.FleetTracker;component/Resources/Images/tick.png" Visibility="{Binding IsCompleted, Converter={StaticResource boolToVis}}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

Any ideas?

EDIT: This is using MVVM so there is no code behind just a bounded ViewModel

回答1:

Okay, I'll try again. Have you tried a CellTemplate with a TextBlock with TextWrapping set to Wrap?

For Example:

<ListView x:Name="MyListView">
   <ListView.View>
      <GridView>
         <GridViewColumn Header="Hello"
                         Width="50">
            <GridViewColumn.CellTemplate>
               <DataTemplate>
                  <TextBlock Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce non nibh quis odio aliquet venenatis."
                             TextWrapping="Wrap"/>
               </DataTemplate>
            </GridViewColumn.CellTemplate>
         </GridViewColumn>
         <GridViewColumn Header="World"/>
      </GridView>
   </ListView.View>

   <ListViewItem/>
   <ListViewItem/>
   <ListViewItem/>
   <ListViewItem/>
</ListView>


回答2:

First, the CellTemplate is the way to go to have custom content inside a cell. You could for example have a vertical StackPanel inside the CellTemplate.

Next, To have the content of your cell resized automatically when you change the column width, you need to specify HorizontalContentAlignment="Stretch" on the ListViewItem:

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
</ListView.ItemContainerStyle>


回答3:

Bear with me as I'm not 100% sure this is what you're asking for. But, assuming you're wanting to have each row have more text underneath it (a la the outlook autopreview feature), I think I can help.

You'll need to override the default style for ListViewItem and change the ControlTemplate to add a TextBlock underneath the GridViewRowPresenter. When you're done, it'll look something like this:

<Style TargetType="ListViewItem">
   <Setter Property="SnapsToDevicePixels" Value="true"/>
   <Setter Property="OverridesDefaultStyle" Value="true"/>
   <Setter Property="Template">
   <Setter.Value>
      <ControlTemplate TargetType="ListBoxItem">
         <Border Name="Border"
                 Padding="2"
                 SnapsToDevicePixels="true"
                 Background="Transparent">
            <StackPanel>
               <GridViewRowPresenter Columns="{TemplateBinding GridView.ColumnCollection}"  
                                     VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
               <TextBlock Text="This is where your text goes!"/>
            </StackPanel>
         </Border>

         <ControlTemplate.Triggers>
            <Trigger Property="IsSelected" Value="true">
               <Setter TargetName="Border"
                       Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="false">
               <Setter Property="Foreground" 
                       Value="{StaticResource DisabledForegroundBrush}"/>
            </Trigger>
         </ControlTemplate.Triggers>
         </ControlTemplate>
   </Setter.Value>
   </Setter>
</Style>

You may have to get fancy with binding the Width of your TextBlock so that it will wrap within the ListView, but this should get you started.



回答4:

This is what I did.

            <GridView ColumnHeaderToolTip="Addendum Master" >
                    <GridViewColumn Width="500">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>                                    
                                <StackPanel Orientation="Vertical" Margin="0">
                                    <Label Content="{Binding Path=Line1}" Padding="0" Margin="0" Style="{StaticResource GridLabelStyle}"></Label>
                                    <Label Content="{Binding Path=Line2}" Padding="0" Margin="0" Style="{StaticResource GridLabelStyle}"></Label>
                                    <Label Content="{Binding Path=Line3}" Padding="0" Margin="0" Style="{StaticResource GridLabelStyle}"></Label>
                                    <Label Content="{Binding Path=Line4}" Padding="0" Margin="0" Style="{StaticResource GridLabelStyle}"></Label>
                                </StackPanel>                                                                        
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>


回答5:

Here is what I feel is a simple solution to a problem that many have run into when it comes to 2 rows per record while still being able to use paging and sorting etc. that comes with the gridview controls. I will give you the code and try to explain it as best I can.

    <Columns>                            
        <asp:BoundField DataField="CPTCode" HeaderText="CPTCode" ItemStyle-CssClass="center" SortExpression="CPTCode" >
            <ItemStyle CssClass="center" />
        </asp:BoundField>

            <asp:BoundField DataField="InsPlanCode" HeaderText="InsPlanCode" ItemStyle-CssClass="center" SortExpression="InsPlanCode" >
            <ItemStyle CssClass="center" />
        </asp:BoundField>

            <asp:BoundField DataField="StartDate" HeaderText="Start Date" ItemStyle-CssClass="center" SortExpression="StartDate" >
            <ItemStyle CssClass="center" />
        </asp:BoundField>

            <asp:BoundField DataField="EndDate" HeaderText="End Date" ItemStyle-CssClass="center" SortExpression="EndDate" >
            <ItemStyle CssClass="center" />
        </asp:BoundField>

        <asp:BoundField DataField="UserName" HeaderText="UserName" ItemStyle-CssClass="center" >
            <ItemStyle CssClass="center" />
        </asp:BoundField>   

        <asp:TemplateField HeaderText=" " ItemStyle-CssClass="center" HeaderStyle-BackColor="AliceBlue" ItemStyle-BackColor="AliceBlue">                                
            <ItemTemplate>        

                </td>
                </tr>
                <tr>
                    <td align="center" nowrap>&nbsp;<b>Message</b>&nbsp;</td>
                    <td colspan="10"><TABLE cellpadding=5><tr><td><%# Eval("carveOutMessage")%></td></tr></TABLE>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>

</asp:GridView>

The trick is in the custom TemplateField ItemTemplate.

The first thing to know is that what renders in the html source when you create a TemplateField, is an new open and closing TD tag. after the last column is created it then closes the row with a closing tag. So create the templatefield open and close as well as the open and close ItemTemplate tags. Inside of that the first thing you want to do is close the open td tag "" and then the open tr tag "". Then create a new row and a new column tag. now if the column needs to be wide for some sort of description or notes column. use columnspan = 10 or however many you need there. Because the Templatefield will close the TD tag your last td tag should not have a closing tag and your last row should not have a closing TR tag because that will get closed out where the closing tag is.

I hope this helps and was clear enough for people to understand. You can using this method to create as many rows as you want per record. Also do any number of other formatting thing if you are any good with html and tables. The key is to remember that when you start you are formatting inside an open td and tr tag and at the end it will write in a closing td and tr tag so leave your last column and row open.