带有ScrollBar的自动宽度ListBox

时间:2018-03-12 11:26:07

标签: wpf

下面的代码和屏幕截图显示了我在下面遇到的问题。

我需要有一个宽度设置为自动的列表框,因为内容大小是可变的。但是,进入列表框的项目数也会发生变化,因此有时需要ScrollBar。问题是,根据下面的图像,自动宽度似乎不适合使用滚动条。我可以添加一个边距,但是当不需要滚动条时我不想要间隙。

我注意到当文本框中放置了一个长字符串时,这只是一个问题,如果输入了一个短/没有字符串,则滚动条正确显示。

除了检测是否需要ScrollBar并动态添加保证金之外,有没有办法做到这一点?我觉得应该有一种方法可以在我的XAML中实现这一点,同时仍然保持列表框列为Width = Auto。

private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
    for (int i = 0; i < 200; i++)
    {
        lbxDocs.Items.Add("TESTSTRING"+i);
    }

    txtImagePath.Text =
        @"uPPvU18ijL9Tz6fqvwLsymkdxuS8h8jS9afzQ8i7LLXvrb2JO2hmPImVF5Dq5PZpdOkw2sTX9j6GeGL7IsaDuaf1ltY0MdzCRHGTZlUVkMa43meW3gavXAWMHyLPiyfGlHxuXcQOoH8ldxkYuxhVRcSJY3ZyCzlCsPjWuINTQyJCAU5hiDqroXWI8"+
        "uPPvU18ijL9Tz6fqvwLsymkdxuS8h8jS9afzQ8i7LLXvrb2JO2hmPImVF5Dq5PZpdOkw2sTX9j6GeGL7IsaDuaf1ltY0MdzCRHGTZlUVkMa43meW3gavXAWMHyLPiyfGlHxuXcQOoH8ldxkYuxhVRcSJY3ZyCzlCsPjWuINTQyJCAU5hiDqroXWI8";
}
<Window x:Class="Grid_ScrollBar.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Grid_ScrollBar"
        mc:Ignorable="d" Loaded="MainWindow_OnLoaded"
        TextOptions.TextRenderingMode="ClearType" WindowStartupLocation="CenterScreen"
        TextOptions.TextFormattingMode="Display" Height="400" Width="500">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBox Name="txtImagePath"/>

        <ListBox Name="lbxDocs" Grid.Column="1" Grid.Row="1"/>
    </Grid>
</Window>

滚动条被切断;

enter image description here

一旦我们点击ListBox中较长的字符串项,宽度会增加以显示滚动条的其余部分;

enter image description here

2 个答案:

答案 0 :(得分:1)

问题是你要告诉文本框占用所有可用空间,即ListBox留下的所有空间。现在,由于列表框的第一个元素占用“较少”的空间,WPF会为它们授予尽可能小的空间,并且不会计算滚动条的大小。

当你遇到这种问题(内容的大小非常可能)时,我最好的建议是不要将宽度设置为自动。而是使用比例大小调整(这也将避免物理移位列的影响,为列表框项目腾出更多空间)。

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="9*"/>
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <TextBox Name="txtImagePath" Grid.Column="0" Grid.Row="0" TextWrapping="Wrap" Margin="0,0,10,0"/>

    <ListBox Name="lbxDocs" Grid.Column="1" Grid.Row="1" />
</Grid>

您还可以添加TextWrapping =“Wrap”以显示全文。

但是如果你真的想要将宽度保持为自动,你可以强迫wpf使用

计算滚动条。
    <ScrollViewer  Grid.Column="1" Grid.Row="1">
        <ListBox Name="lbxDocs"/>
    </ScrollViewer>

编辑:要解决滚动查看器的问题,您需要将列表框的高度设置为滚动查看器的高度,否则自动设置将不起作用:

    <ScrollViewer x:Name="test" Grid.Column="1" Grid.Row="1" VerticalScrollBarVisibility="Auto">
        <ListBox Name="lbxDocs" Height="{Binding ElementName=test, Path=ActualHeight}"/>
    </ScrollViewer>

答案 1 :(得分:0)

尝试将scrollview添加到listview,而不更改其余的xaml

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBox Name="txtImagePath"/>
        <ListBox Name="lbxDocs" 
                 Grid.Column="1" 
                 Grid.Row="1"  
                 ScrollViewer.CanContentScroll="True"
                 ScrollViewer.VerticalScrollBarVisibility="Auto"
                 ScrollViewer.HorizontalScrollBarVisibility="Auto"
        />

Width = "*"表示您将使用所有剩余的可用空间。 Width = "Auto"表示您将调整内容的大小,以便所有内容都适合而不是超出任何多余的空间

所以(正如你所做的)在你的窗口中将第1列调整为列表视图的大小,将第0列调整为窗口的其余部分。