WPF - Как определенные элементы ListView охватывают столбцы? - PullRequest
4 голосов
/ 19 октября 2010

У меня есть набор данных, которые я хотел бы представить через WPF ListView следующим образом:

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

Я начинаю с работы с этим базовым образцом: http://msdn.microsoft.com/en-us/library/ms771309(VS.90).aspx

Item4 и Item7 выше имеют длинный текст, который я хотел бы охватить оставшимися столбцами (игнорируя, для чего предназначались исходные заголовки столбцов).Как я могу это сделать?

У меня уже есть некоторые настройки XAML с DataTrigger для замены стандартного GridViewRowPresenter на собственный TextBlock, но это не совсем то, что я ищу.Мне нужно, чтобы данные в столбце 1 отображались нормально, а ширина первого столбца была распознана.

Ответы [ 3 ]

7 голосов
/ 17 декабря 2010

Вот как я решил эту проблему с помощью правильного 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>

Ключ в том, что шаблон DataTriggered не использует GridViewRowPresenter, а вместо этого подделывает его использование с собственной сеткой.Некоторые из отступов / полей нужно было угадать, чтобы они соответствовали тому, что GridViewRowPresenter использует внутри.Другая сложная часть заключалась в привязке внутренних столбцов Grid к общей ширине столбцов ListView.Изменение размера столбцов затем работает как ожидалось.

0 голосов
/ 23 мая 2019

У меня похожая проблема, когда я хочу, чтобы в некоторых строках содержался элемент, охватывающий несколько столбцов, который начинается в 5-м (из девяти) столбцах. Я реализовал вариант ответа @ PeteVasi с двумя основными изменениями:

  • Вы хотите связать с ActualWidth, а не Width, или это не работает, когда, например, колонки имеют авторазмер.
  • Вы можете использовать RelativeSource, чтобы не указывать myListView по имени (что делает его более подходящим для использования в ресурсе стиля).

Для этого измените назначение Width в записях ColumnDefinition из этого:

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

к этому:

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

Кроме того, вам не нужно использовать вложенный <Grid>, и если вы хотите сохранить эффекты наведения мыши и выделения, вам нужно клонировать стиль по умолчанию.

Я экспериментировал с небольшим вариантом ответа, который использует GridViewRowPresenter, и играл с плохой идеей (отслеживая события изменения размера столбца и используя их, чтобы установить свойство, к которому привязана ширина столбца). Различные эксперименты, включая полностью стилизованную версию, можно найти в проекте DisasmUiTest на github .

0 голосов
/ 20 октября 2010

Я думаю, для этого вы используете ListBox вместо ListView и используете его ItemTemplate для разделения каждого столбца.

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

Таким образом, у вас будет возможность добавить триггер или на основе некоторых данных, вы можете сделать один элемент управления невидимым и показать длинный текст.

:)

...