How can I group GridViewColumns in WPF, so the expander fills the whole width

感情迁移 提交于 2019-12-24 18:18:21

问题


I am new to WPF and try to do the following:

I have a ListView with a ItemsSource using a ViewModel. Inside, there is a GridView with Columns. Each Column represents a Preoperty of the View Model. But the Description is optional and can be rather long. So I want to use a Expander. My Problem is, that I can only manage the expander to be as big as the Name-Column. But I want the expander to be as big as the whole row. Here are 2 Images to clarify what I want.

My current State: https://i.stack.imgur.com/ZNA4v.png

What I want to achieve: https://i.stack.imgur.com/ZmFq1.png

I tried "grouping the GridView" but without success... See here http://technico.qnownow.com/grouping-gridview-wpf/

Here's my Code

<Window ...>
<Window.Resources>
    ...
</Window.Resources>
<DockPanel>
    <StackPanel DockPanel.Dock="Top">
        ...
    </StackPanel>
    <Grid>            
        <ListView Grid.RowSpan="4" DockPanel.Dock="Top" Margin="10" ItemsSource="{Binding MyView}">
            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}">
                    <Setter Property="BorderBrush" Value="Black"></Setter>
                    <Setter Property="BorderThickness" Value="0,0,0,1"></Setter>
                    <Setter Property="Focusable" Value="False" />
                    <Setter Property="HorizontalAlignment" Value="Stretch" />
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                    <Setter Property="VerticalAlignment" Value="Top"></Setter>
                    <Setter Property="VerticalContentAlignment" Value="Top"></Setter>
                </Style>
            </ListView.ItemContainerStyle>

            <!-- New GridView -->
            <ListView.View>
                <GridView>

                    <!--Number-->
                    <GridViewColumn Header="#">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate DataType="viewModel:MyViewModel">
                                <TextBlock Text="{Binding Model.Number, StringFormat='#{0}', Mode=OneWay}"
                                               Width="20" TextAlignment="Left" Margin="5" VerticalAlignment="Top" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <!--ErrorLevel-->
                    <GridViewColumn Header="" Width="45">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate DataType="viewModel:MyViewModel">
                                <Image Source="{Binding Model.ErrorLevel, Converter={StaticResource ErrorLevelToImageConverter}, Mode=OneWay}"
                                           ToolTip="{Binding Model.ErrorLevel, Mode=OneWay}" Width="20" Margin="5" VerticalAlignment="Top" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <!--ID-->
                    <GridViewColumn Header="ID">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate DataType="viewModel:MyViewModel">
                                <TextBlock TextAlignment="Center" Margin="5" Width="50" VerticalAlignment="Top" >
                                        <Hyperlink NavigateUri="{Binding Model.Hyperlink, Mode=OneWay}"
                                                   Command="{Binding HyperlinkCommand}">
                                            <TextBlock Text="{Binding Model.Id, Mode=OneWay}" />
                                        </Hyperlink>
                                    </TextBlock>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <!--Name-->
                    <GridViewColumn Header="Name" Width="500" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate DataType="viewModel:MyViewModel">
                                <Expander ToolTip="Expand" ExpandDirection="Down" Foreground="Black" VerticalAlignment="Top">
                                    <Expander.Header>
                                        <TextBlock Text="{Binding Model.Name, Mode=OneWay}"
                                               HorizontalAlignment="{Binding HorizontalAlignment, RelativeSource={RelativeSource AncestorType=ContentPresenter}, Mode=OneWayToSource}"
                                               TextAlignment="Left" Margin="5" TextWrapping="Wrap" VerticalAlignment="Top" />
                                    </Expander.Header>
                                    <GroupBox Header="Description" FontWeight="Bold" >
                                        <TextBlock Text="{Binding Model.Description, Mode=OneWay}" TextWrapping="Wrap"
                                                       FontWeight="Normal" TextAlignment="Left" Margin="5" />
                                    </GroupBox>
                                </Expander>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <!-- Module-->
                    <GridViewColumn Header="Module" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate DataType="viewModel:MyViewModel">
                                <TextBlock Text="{Binding Model.Module, Mode=OneWay}"
                                               TextAlignment="Center" Margin="5" Width="100" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</DockPanel>

Once again, i am new to WPF, MVVM, DataBinding and all this. So please try to make your answer as detailed as possible. I tried many things, but they didn't work out.


回答1:


You could add the following GridViewColumn at the left side (top in XAML) to your GridView

<GridViewColumn Header="" Width="30">
    <GridViewColumn.CellTemplate>
        <DataTemplate DataType="viewModel:MyViewModel">
            <Expander Margin="-5,2,-5000,0" HorizontalAlignment="Left" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ItemsPresenter}}}">
                <GroupBox Header="Description" FontWeight="Bold" Margin="0,0,5,0">
                    <TextBlock Text="{Binding Model.Description}" FontWeight="Normal" TextWrapping="Wrap" />
                </GroupBox>
            </Expander>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

This is GridViewColumncontains an empty Header which simply shows the Expander-Arrow in the GridViewRows.

The Expander itself is left aligned and has a huge negative Margin on the right side, so it can draw its content outside of the right boundary. The width is set to the ActualWidth of the ItemsPresenter of your GridView. With this Width you can limit the content to the current visible Width of the GridView (Or you can set it to an absolute value like 500).

And finally a preview of this Column




回答2:


OK, the fact that the expander is not stretchable is because of the non stretchable parent control. You have a column 'Name' in your gridview with a fixed width and a expander added as a child. As far as i know the child control cannot extend beyond the parent control if this is not truth im sure someone will correct this. I don't know what the best way is to achieve your goal but to give you some inspiration i made a small example.

So, to give you a example if how this could work:

Edit: You can just set negative margins on your expander like so:

<Expander ToolTip="Expand" ExpandDirection="Down" Margin="-100,0,-300,0" Foreground="Black" VerticalAlignment="Top">

Thanks to @LittleBit for this tip.

<ListView x:Name="lsttest" ItemsSource="{Binding persons}">
        <ListViewItem>
            <StackPanel>
                <ListView>
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Header="#1" Width="50">
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Name}"
                                           Width="20" TextAlignment="Left" Margin="5" VerticalAlignment="Top" />
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                            <GridViewColumn Header="Test 2" Width="50">
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Name}"
                                           Width="20" TextAlignment="Left" Margin="5" VerticalAlignment="Top" />
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                        </GridView>
                    </ListView.View>
                </ListView>
                <Expander ToolTip="Expand" ExpandDirection="Down" Foreground="Black" VerticalAlignment="Top">
                    <Expander.Header>
                        <TextBlock Text="{Binding Model.Name, Mode=OneWay}"
                                           HorizontalAlignment="{Binding HorizontalAlignment, RelativeSource={RelativeSource AncestorType=ContentPresenter}, Mode=OneWayToSource}"
                                           TextAlignment="Left" Margin="5" TextWrapping="Wrap" VerticalAlignment="Top" />
                    </Expander.Header>
                    <GroupBox Header="Description" FontWeight="Bold" Width="{Binding ActualWidth, ElementName=lsttest}">
                        <TextBlock Text="{Binding Name, Mode=OneWay}" TextWrapping="Wrap"
                                                   FontWeight="Normal" TextAlignment="Left" Margin="5" />
                    </GroupBox>
                </Expander>
            </StackPanel>
        </ListViewItem>
        </ListView>

The result:



来源:https://stackoverflow.com/questions/54252768/how-can-i-group-gridviewcolumns-in-wpf-so-the-expander-fills-the-whole-width

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!