1

私は、ListBox基本的にキャンバスであるを持っています。アイテムはとして表示されRectanglesます。ListBoxItem's Canvas.Left長方形の位置は、 andCanvas.Rightプロパティを介してアイテムのデータにバインドされます。

これはListBox' Template、を生成しCanvasます。

<ListBox.Template>
    <ControlTemplate>
        <Canvas IsItemsHost="True"/>
    </ControlTemplate>
</ListBox.Template>

アイテムのListBox' ItemContainerStyle位置を設定します。

<Style TargetType="ListBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <ContentPresenter/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Canvas.Left">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource ...}">
                ...
            </MultiBinding>
        </Setter.Value>
    </Setter>
    <Setter Property="Canvas.Right">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource ...}">
                ...
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Style>

これは実際に機能します。を境界線で囲むContentPresenterと、境界線の位置とサイズが正しくなります。

これで、長方形は実際の幅Widthと等しくなるはずです。ListBoxItem'sしたがって、ItemTemplate次のようになります。

<DataTemplate>
    <Rectangle Height="..." 
       Width="{Binding ActualWidth,
         RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}}" 
       Fill="..."/>
</DataTemplate>

ただし、このバインディングを適用すると、長方形は表示されません。一定の幅を設定すると、すべてが正しくレンダリングされます。

長方形内の長方形の位置を設定する方法はありCanvasますか?

アップデート

WPFツリービジュアライザーを使用して、これがおそらくの問題であることに気付きましたContentPresenter's ActualWidth。次のスクリーンショットは、Canvas.LeftandCanvas.Rightプロパティが正しく設定されて いることを示しています。ツリービジュアライザーのスクリーンショット

ただし、ActualWidthプロパティは4に設定されています(StrokeThickness含まれているのRectangleは4です)。このレイアウトの問題はどのように解決できますか?

さらに、私は上記の私の声明を修正しなければなりません。をで囲むContentPresenterBorder、正しい結果が得られません。代わりに、レイアウト全体が壊れているようです。

アップデート2

MSDNは次のように述べています。

子要素のCanvas.Rightオフセットは、親Canvasのサイズには影響しません。

それらを指定すると、添付されたプロパティCanvas.TopまたはCanvas.LeftがCanvas.BottomまたはCanvas.Rightプロパティよりも優先されます

したがって、幅を明示的に指定する必要があるようです。これは、適切なコンバーターでは小さな問題になるはずです。

4

2 に答える 2

0

質問で述べたように、コントロールのサイズをCanvas.LeftCanvas.Rightプロパティだけで定義することはできません。

必要な動作は、次のようなコンバーターで実現できます (エラー処理は省略されています)。

public class CanvasWidthConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var canvasLeft = (double)values[0];
        var canvasRight = (double)values[1];

        return canvasRight - canvasLeft;
    }

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

使用 (コンバーターをリソースとして追加):

<Style TargetType="ListBoxItem">
    <Setter Property="Canvas.Left" Value="{Binding LeftValue}"/>
    <Setter Property="Width">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource CanvasWidthConverter}">
                <Binding Path="LeftValue"/>
                <Binding Path="RightValue"/>
            </MultiBinding>
         </Setter.Value>
     </Setter>
</Style>
于 2012-10-12T16:07:39.370 に答える