WPF listview/gridsplitter/scrollviewer调整大小问题

发布于 2024-11-15 21:10:52 字数 2791 浏览 5 评论 0原文

我有一个问题,网格分割器将我的列表视图推到这个组合的视图之外。重现步骤:

  • 启动程序,将窗口尺寸拖动得更大
  • 将红色分隔线一直向左拖动以最小化蓝色列
  • 加宽两个 ListView 列,直到它们位于视口之外并出现水平滚动条
  • 再次将窗口尺寸拖动得更小

对于我来说,这慢慢地将 ListView 推到 Window 之外。请注意,ScrollViewer 的大小实际上随 Window 一起减小,但速度不同,并且会慢慢消失在视图中。一旦滚动查看器开始滑出视图,分离器就不能再使用了!

奇怪的是,如果我不首先最小化左侧面板,我就不会出现这种行为!

有什么办法可以解决这个问题?

<Window x:Class="LayoutTest3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="600" Width="800" MinHeight="600" MinWidth="800" >
    <Window.Resources>
        <XmlDataProvider XPath="/Celebrities/Celebrity" x:Key="celebs">
            <x:XData>
                <Celebrities xmlns="">
                    <Celebrity Name="Jimmy">
                        <LastName>Page</LastName>
                    </Celebrity>
                    <Celebrity Name="Johnny">
                        <LastName>Depp</LastName>
                    </Celebrity>
                    <Celebrity Name="Britney">
                        <LastName>Spears</LastName>
                    </Celebrity>
                </Celebrities>
            </x:XData>
        </XmlDataProvider>

        <DataTemplate x:Key="NameTemplate">
            <TextBlock Text="{Binding XPath=@Name}" />
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" MinWidth="100" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" MinWidth="400" />
        </Grid.ColumnDefinitions>
        <Border Grid.Column="0" Background="Blue" />
        <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center" ResizeBehavior="PreviousAndNext" VerticalAlignment="Stretch" Background="Red" />
        <Border Grid.Column="2" Background="Green">
            <ListView ItemsSource="{Binding Source={StaticResource celebs}}">
                <ListView.View>
                    <GridView>
                        <GridView.Columns>
                            <GridViewColumn Header="Name" CellTemplate="{StaticResource NameTemplate}" Width="150" />
                            <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding XPath=LastName}" />
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
            </ListView>
        </Border>
    </Grid>
</Window>

I have a problem with the gridsplitter pushing my listview out of view in this combination. Steps to reproduce:

  • Start program, drag the window size larger
  • Drag the red splitter all the way left to minimize the blue column
  • Widen both ListView columns until they are outside the viewport and a horizontal scroll appears
  • Drag the window size smaller again

For me, this slowly pushes the ListView outside the Window. Note the ScrollViewer is actually decreasing in size with the Window, but not at the same rate and slowly goes out of view. Once the scrollviewer starts slipping out of view the splitter cannot be used any more!

Oddly enough, if I don't minimize the left panel first I don't get this behavior!

What would be a fix for this?

<Window x:Class="LayoutTest3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="600" Width="800" MinHeight="600" MinWidth="800" >
    <Window.Resources>
        <XmlDataProvider XPath="/Celebrities/Celebrity" x:Key="celebs">
            <x:XData>
                <Celebrities xmlns="">
                    <Celebrity Name="Jimmy">
                        <LastName>Page</LastName>
                    </Celebrity>
                    <Celebrity Name="Johnny">
                        <LastName>Depp</LastName>
                    </Celebrity>
                    <Celebrity Name="Britney">
                        <LastName>Spears</LastName>
                    </Celebrity>
                </Celebrities>
            </x:XData>
        </XmlDataProvider>

        <DataTemplate x:Key="NameTemplate">
            <TextBlock Text="{Binding XPath=@Name}" />
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" MinWidth="100" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" MinWidth="400" />
        </Grid.ColumnDefinitions>
        <Border Grid.Column="0" Background="Blue" />
        <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center" ResizeBehavior="PreviousAndNext" VerticalAlignment="Stretch" Background="Red" />
        <Border Grid.Column="2" Background="Green">
            <ListView ItemsSource="{Binding Source={StaticResource celebs}}">
                <ListView.View>
                    <GridView>
                        <GridView.Columns>
                            <GridViewColumn Header="Name" CellTemplate="{StaticResource NameTemplate}" Width="150" />
                            <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding XPath=LastName}" />
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
            </ListView>
        </Border>
    </Grid>
</Window>

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

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

发布评论

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

评论(3

红玫瑰 2024-11-22 21:10:52

GridSplitter 和具有 MinWidth 的 Column 存在一个已知问题,GridSplitter 仍然会调整 Grid 大小而忽略 Column 的 MinWidth。其结果是,不断增长的列的子项获得的大小比实际可用的大小更大。但是 Grid 布局子项会考虑 MinWidth,因此您的 Shrinking 列仍保持 MinWidth,但 Growing Column 的子项会超出 GridSplitter 超出收缩列的 MinWidth 的大小。

我将找出如何在我的一个项目中解决这个问题,并且我将发布代码。同时您可以尝试以下选项。

  1. 从 ColumnDefinition 中删除 MinWidth
  2. 将 MinWidth 添加到 Child

提前知道 Grid 的最小大小应为 500 + Splitter 的大小,您可以设置整个 Grid 的 MinWidth。

There is a known problem with GridSplitter and Column with MinWidth, GridSplitter still resized Grid ignoring Column's MinWidth. Result of that is the growing column's child gets more size the actually available. But Grid layouts children considering MinWidth and thus your Shrinking column remains at MinWidth but Growing Column's child goes out of view of the size that GridSplitter has gone beyond MinWidth of shrinking column.

I am going to find out how did I solve this in my one of the project and I will post code. Meanwhile you can try following options.

  1. Remove MinWidth from ColumnDefinition
  2. Add MinWidth to Child

Knowing in advance that your Grid's Minimum Size should be 500 + Size of Splitter, you can set MinWidth of entire Grid.

羁客 2024-11-22 21:10:52

我是这样做的:

<Grid Name="container" SizeChanged="container_SizeChanged">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Name="rightPanel" Width="*" MinWidth="100"/>
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="0" Background="Red" Foreground="White">Test</TextBlock>
    <GridSplitter Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Right" Width="2" Height="Auto" ResizeDirection="Columns"/>
    <Border Grid.Column="1" Background="Green" Margin="0 0 0 0">
        <ListView ItemsSource="{Binding Source={StaticResource celebs}}">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Name" CellTemplate="{StaticResource NameTemplate}" Width="150" />
                        <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding XPath=LastName}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
    </Border>
</Grid>

以及后面的代码(恶心!):

private void container_SizeChanged(object sender, SizeChangedEventArgs e)
{
    rightPanel.MaxWidth = container.ActualWidth - 150;
}

基本上,您取出最小宽度并执行类似的计算以在另一个面板上设置 MaxWidth。

Here's how I did it:

<Grid Name="container" SizeChanged="container_SizeChanged">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Name="rightPanel" Width="*" MinWidth="100"/>
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="0" Background="Red" Foreground="White">Test</TextBlock>
    <GridSplitter Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Right" Width="2" Height="Auto" ResizeDirection="Columns"/>
    <Border Grid.Column="1" Background="Green" Margin="0 0 0 0">
        <ListView ItemsSource="{Binding Source={StaticResource celebs}}">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Name" CellTemplate="{StaticResource NameTemplate}" Width="150" />
                        <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding XPath=LastName}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
    </Border>
</Grid>

and code behind (yuck!):

private void container_SizeChanged(object sender, SizeChangedEventArgs e)
{
    rightPanel.MaxWidth = container.ActualWidth - 150;
}

Basically you take out the min width and perform a similar calculation to set MaxWidth on the other panel.

辞慾 2024-11-22 21:10:52

也许这会有所帮助,您始终必须使用相同类型的宽度/高度单位,否则分割器将无法正常工作。

 <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" MinWidth="150"/>
        <ColumnDefinition Width="4*" MinWidth="150"/>
    </Grid.ColumnDefinitions>

    <ListView Grid.Column="0" BorderBrush="#FF005BFF" Margin="0,0,5,0">
        <ListView.View>
            <GridView>
                <GridViewColumn />
            </GridView>
        </ListView.View>
    </ListView>

    <GridSplitter Grid.Column="1" 
                  HorizontalAlignment="Left" VerticalAlignment="Stretch" 
                  Background="Black" 
                  ShowsPreview="true"
                  Width="2" />

    <ListView Grid.Column="1" BorderBrush="#FFFF5100" Margin="5,0,0,0">
        <ListView.View>
            <GridView>
                <GridViewColumn />
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

Maybe this can help, you always have to use the same type of unit for width / height, or the splitter wont work correctly.

 <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" MinWidth="150"/>
        <ColumnDefinition Width="4*" MinWidth="150"/>
    </Grid.ColumnDefinitions>

    <ListView Grid.Column="0" BorderBrush="#FF005BFF" Margin="0,0,5,0">
        <ListView.View>
            <GridView>
                <GridViewColumn />
            </GridView>
        </ListView.View>
    </ListView>

    <GridSplitter Grid.Column="1" 
                  HorizontalAlignment="Left" VerticalAlignment="Stretch" 
                  Background="Black" 
                  ShowsPreview="true"
                  Width="2" />

    <ListView Grid.Column="1" BorderBrush="#FFFF5100" Margin="5,0,0,0">
        <ListView.View>
            <GridView>
                <GridViewColumn />
            </GridView>
        </ListView.View>
    </ListView>
</Grid>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文