1

请参阅帖子底部的更新

我正在使用 .Net 4.5 编写 WPF 应用程序

我有一个ListBox显示电影信息,xaml 如下所示。

<ListBox Margin="10, 5, 10, 10"
             ItemsSource="{Binding SearchResponse.Results}"
             HorizontalAlignment="Stretch"
             VerticalAlignment="Stretch">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <EventSetter Event="MouseDoubleClick"
                             Handler="SearchResult_OnMouseDoubleClick">
                </EventSetter>
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border BorderBrush="#3e3e42"
                        BorderThickness="1"
                        CornerRadius="5"
                        Background="#242424"
                        Padding="10">
                    <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding ThumbnailPath}"
                               Width="{Binding RelativeSource={RelativeSource FindAncestor,
                                AncestorType={x:Type Window}},
                                Path=DataContext.ThumbnailWidth}"
                               Height="{Binding RelativeSource={RelativeSource FindAncestor,
                                AncestorType={x:Type Window}},
                                Path=DataContext.ThumbnailHeight}"
                               Margin="0,0,10,0" />
                        <StackPanel TextBlock.FontFamily="Segoe WP"
                                    TextBlock.FontSize="14"
                                    TextBlock.Foreground="WhiteSmoke"
                                    Width="300">
                            <TextBlock Text="{Binding Title}"
                                       TextTrimming="CharacterEllipsis" />
                            <TextBlock Text="{Binding Description}"
                                       TextTrimming="CharacterEllipsis"
                                       TextWrapping="Wrap"/>
                            <TextBlock Text="{Binding Path}"
                                       TextTrimming="CharacterEllipsis"/>
                        </StackPanel>
                    </StackPanel>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

列表中的每个缩略图(图像)都将具有相同的宽度和高度(小、中或大)。对于我拥有SizeToContent=Width的窗口,当缩略图大小更改时,窗口将自行调整大小。

问题是这样的:当我ListBox使用鼠标滚轮滚动时,ListBox宽度看似随机变化并导致窗口宽度增加。如果我使用滚动条向上和向下按钮滚动,则不会发生这种情况。

我已经调试了项目数据模板ActualWidth中的所有元素ListBox(文本块、堆栈面板、边框等),它们都保持在预期的固定宽度,但调试列表框本身的宽度表明它随机改变宽度.

这是两个屏幕截图。第一个显示正确的布局,第二个显示ListBox用鼠标滚轮滚动后的布局。

正确的布局

滚动后,列表框变宽了!

那么,为什么其中ListBox ActualWidth包含的项目没有变化?

更新: 一些进一步的调查表明,这种行为是由于我用于缩略图的图像大于缩略图显示大小并且由图像控件调整大小造成的。似乎列表框(有时)根据原始图像大小而不是较小的调整大小的图像调整大小。

有人有任何建议来克服这个问题吗?

4

1 回答 1

0

我设法通过编写一个MultiValueConverter接受图像文件路径和像素宽度(使用 MultiBinding 在 xaml 中绑定)并返回正确大小的位图以显示在缩略图图像控件中来解决此问题。结果是使用(并缓存)正确大小的图像,因此ListBox宽度是恒定的。

这是转换器的代码:

public class PathToThumbnailConverter : IMultiValueConverter 
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var path = values[0] as string;
        var decodeWidth = (int)values[1];

        if (!string.IsNullOrEmpty(path))
        {
            var info = new FileInfo(path);

            if (info.Exists && info.Length > 0)
            {
                var bi = new BitmapImage();

                bi.BeginInit();
                bi.DecodePixelWidth = decodeWidth;
                bi.CacheOption=BitmapCacheOption.OnLoad;
                bi.UriSource=new Uri(info.FullName);
                bi.EndInit();

                return bi;
            }
        }
        return null;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

这是声明它的xaml:

<Window.Resources>
    <valueConverters:PathToThumbnailConverter x:Key="ThumbConverter"/>
</Window.Resources>

并使用它:

<Image.Source>
   <MultiBinding Converter="{StaticResource ThumbConverter}">
    <Binding Path="ThumbnailPath"/>
    <Binding RelativeSource="{RelativeSource FindAncestor,
        AncestorType={x:Type Window}}" Path="DataContext.ThumbnailWidth"/>
   </MultiBinding>
</Image.Source>
于 2013-06-13T15:14:19.540 回答