سؤال

I have a set of data that I'd like to present via a WPF ListView in this way:

Column1   Column2   Column3
--GroupName1--
Item1     part2     part3
Item2     part2     part3
--GroupName2--
Item3     part2     part3
Item4     long_text_in_both_columns
Item5     part2     part3
--GroupName1--
Item6     part2     part3
Item7     long_text_in_both_columns
--GroupName3--
Item8     part2     part3

I am starting by working with this basic sample: http://msdn.microsoft.com/en-us/library/ms771309(VS.90).aspx

Item4 and Item7 above have long text that I would like to span the remaining columns (ignoring what the original column headings were for). How can I do this?

I already have some XAML setup with a DataTrigger to replace the default GridViewRowPresenter with a custom TextBlock, but this isn't quite what I'm looking for. I need the data in column 1 to be displayed normally and the width of the first column recognized.

هل كانت مفيدة؟

المحلول

Here's how I ended up solving this with a proper ListView:

        <ListView.ItemContainerStyle >
            <Style TargetType="ListViewItem">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ShowAcrossColumns}" Value="True">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListViewItem}">
                                    <Grid>
                                        <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding ElementName=myListView, Path=View.Columns[0].Width}" />
                                                <ColumnDefinition Width="*" />
                                            </Grid.ColumnDefinitions>
                                            <TextBlock Grid.Column="0" Padding="6,3,6,3" Text="{Binding Column1Text}" />
                                            <TextBlock Grid.Column="1" Padding="6,3,6,3" Text="{Binding ColumnSpanningText}" />
                                        </Grid>
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </Style.Triggers>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListViewItem}">
                            <Grid>
                                <GridViewRowPresenter />
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>

The key is that the DataTriggered Template does not use GridViewRowPresenter, and instead fakes the use of it with its own grid. Some of the padding/margins had to be guessed at to sort of match what GridViewRowPresenter uses internally. The other tricky part was binding the internal Grid columns to the overall ListView column widths. Resizing columns then works as expected.

نصائح أخرى

I think for this, you use ListBox instead of ListView and use its ItemTemplate to split each columns.

<ListBox>
<ListBox.ItemTemplate>
 <DataTemplate>
  <StackPanel>
    <TextBlock Text="{Binding Text1}"/>
    <TextBlock Text="{Binding Text2}" />
  </StackPanel>
 </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

In this way you will have chance to put Trigger in or based on some data, you could make one control invisible and show the long text.

:)

I have a similar problem, where I want some lines to have a multi-column-spanning item that starts in the 5th (of nine) columns. I implemented a variation on @PeteVasi's answer, with two main changes:

  • You want to bind to ActualWidth rather than Width, or it doesn't work right when e.g. columns are auto-sized.
  • You can use RelativeSource to avoid specifying myListView by name (which makes it more suitable for use in a style resource).

To do this, change the Width assignment in the ColumnDefinition entries from this:

Width="{Binding ElementName=myListView, Path=View.Columns[0].Width}"

to this:

Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
    AncestorType={x:Type ListView}}, Path=View.Columns[0].ActualWidth}"

Further, you don't need to use a nested <Grid>, and if you want to keep the mouse-over and selection highlighting effects, you need to clone the default style.

I experimented with a minor variation on the answer that uses GridViewRowPresenter, and played with a bad idea (watching for column resize events and using them to set a property to which a column width was bound). The various experiments, including a fully-styled version, can be found in the DisasmUiTest project on github.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top