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.

ここに 2 つのスクリーンショットがあります。1 つ目は正しいレイアウトを示し、2 つ目はListBoxマウス ホイールでスクロールした後のレイアウトを示しています。

正しいレイアウト

スクロール後、リストボックスが広くなる!

ListBox ActualWidthでは、含まれているアイテムが変化しないのに、なぜ変化するのでしょうか?

更新: さらに調査を行うと、サムネイルに使用している画像がサムネイルの表示サイズよりも大きく、画像コントロールによってサイズ変更されているために、この動作が引き起こされていることが示唆されています。リストボックスは、サイズ変更された小さい画像ではなく、元の画像サイズに応じて(時々)サイズ変更されているようです。

これを克服するための提案はありますか?

4

1 に答える 1

0

MultiValueConverter画像ファイル パスとピクセル幅 (MultiBinding を使用して xaml にバインド) を受け取り、正しいサイズのビットマップを返し、サムネイルの Image コントロールに表示することで、この問題を修正することができました。その結果、正しいサイズの画像が使用 (およびキャッシュ) されるため、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 に答える