请参阅帖子底部的更新
我正在使用.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
在其中包含的项目不变时会发生变化?
更新 一些进一步的调查表明,这种行为是由于我用于缩略图的图像大于缩略图显示尺寸并且由图像控件调整大小的事实引起的。看起来列表框(有时)会根据原始图像大小调整大小,而不是调整较小的图像大小。
任何人都有任何建议要克服这个问题吗?
答案 0 :(得分:0)
我设法通过编写MultiValueConverter
来修复此问题,该ListBox
接收图像文件路径和像素宽度(使用MultiBinding在xaml中绑定)并返回正确大小的位图以显示在缩略图Image控件中。结果是使用(和缓存)正确大小的图像,因此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();
}
}
宽度是恒定的。
这是转换器的代码:
<Window.Resources>
<valueConverters:PathToThumbnailConverter x:Key="ThumbConverter"/>
</Window.Resources>
这是声明它的xaml:
<Image.Source>
<MultiBinding Converter="{StaticResource ThumbConverter}">
<Binding Path="ThumbnailPath"/>
<Binding RelativeSource="{RelativeSource FindAncestor,
AncestorType={x:Type Window}}" Path="DataContext.ThumbnailWidth"/>
</MultiBinding>
</Image.Source>
使用它:
{{1}}