WPF - 如何让某些 ListView 项目跨越列?

发布于 2024-09-28 15:13:50 字数 719 浏览 10 评论 0原文

我有一组数据想通过 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 有我想跨越其余列的长文本(忽略原始列标题的用途)。我该怎么做?

我已经使用 DataTrigger 进行了一些 XAML 设置,以将默认的 GridViewRowPresenter 替换为自定义 TextBlock,但这并不是我想要的。我需要第1列中的数据正常显示并识别第一列的宽度。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酸甜透明夹心 2024-10-05 15:13:50

以下是我最终如何使用适当的 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 内部使用的内容。另一个棘手的部分是将内部网格列绑定到整个 ListView 列宽度。然后调整列大小即可按预期工作。

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.

只是偏爱你 2024-10-05 15:13:50

我认为为此,您可以使用 ListBox 而不是 ListView 并使用其 ItemTemplate 来拆分每一列。

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

通过这种方式,您将有机会将触发器放入或基于某些数据,您可以使一个控件不可见并显示长文本。

:)

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.

:)

呆° 2024-10-05 15:13:50

我有一个类似的问题,我希望某些行有一个从第五(九)列开始的多列跨越项目。我对 @PeteVasi 的答案实现了一个变体,有两个主要更改:

  • 您想要绑定到 ActualWidth 而不是 Width,或者当列为 auto 时它无法正常工作- 大小。
  • 您可以使用RelativeSource来避免按名称指定myListView(这使其更适合在样式资源中使用)。

为此,请将 ColumnDefinition 条目中的 Width 分配从: 更改

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

为: 此外

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

,您不需要使用嵌套的 ,如果要保留鼠标悬停和选择高亮效果,则需要克隆默认样式。

我尝试了使用 GridViewRowPresenter 的答案的微小变化,并使用了一个坏主意(观察列调整大小事件并使用它们来设置列宽度绑定的属性)。各种实验(包括完整样式的版本)可以在 github 上的 DisasmUiTest 项目中找到。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文