WPF - Как определенные элементы ListView охватывают столбцы?
У меня есть набор данных, который я хотел бы представить через WPF ListView следующим образом:
Столбец1 Столбец2 Столбец3 --GroupName1-- Item1 часть2 часть3 Item2 часть2 часть3 --GroupName2-- Item3 часть2 часть3 Item4 long_text_in_both_columns Item5 часть2 часть3 --GroupName1-- Item6 часть2 часть3 Item7 long_text_in_both_columns --GroupName3-- Item8 часть2 часть3
Я начинаю с работы с этим базовым образцом: http://msdn.microsoft.com/en-us/library/ms771309(VS.90).aspx
Item4 и Item7 выше имеют длинный текст, который я хотел бы охватить оставшимися столбцами (игнорируя, для чего предназначались исходные заголовки столбцов). Как я могу это сделать?
У меня уже есть некоторые настройки XAML с DataTrigger для замены GridViewRowPresenter по умолчанию на пользовательский TextBlock, но это не совсем то, что я ищу. Мне нужно, чтобы данные в столбце 1 отображались нормально, а ширина первого столбца распознавалась.
2 ответа
Вот как я решил эту проблему с помощью правильного 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 Template не использует GridViewRowPresenter, а вместо этого подделывает использование его со своей собственной сеткой. Некоторые из отступов / полей нужно было угадать, чтобы они соответствовали тому, что GridViewRowPresenter использует внутри. Другая сложная часть заключалась в привязке внутренних столбцов Grid к общей ширине столбцов ListView. Изменение размера столбцов тогда работает как ожидалось.
Я думаю, для этого вы используете ListBox вместо ListView и используете его ItemTemplate для разделения каждого столбца.
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Text1}"/>
<TextBlock Text="{Binding Text2}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Таким образом, у вас будет возможность добавить триггер или на основе некоторых данных, вы можете сделать один элемент управления невидимым и отобразить полный текст.
:)
У меня похожая проблема, когда я хочу, чтобы в некоторых строках содержался многостолбцовый элемент, начинающийся с 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.