2011-10-05 13 views
1

私はListBoxItemのサブクラスとListBoxのサブクラスを作成しました。これはIsItemItsOwnContainerOverrideGetContainerForItemOverrideの両方をオーバーライドしてコンテナとして使用します。幅が変更されたときにListBoxItemがMeasureOverrideを呼び出さないのはなぜですか?

ここで、ウィンドウが最初に表示されたら、ListBoxItem(Infinity、Infinityで)ごとにMeasureOverrideが呼び出され、その後すべての項目でArrangeOverrideが呼び出されます。

ListBoxのサイズを変更する際しかし、唯一ArrangeOverrideは、widthプロパティのメタデータがAffectsMeasureに設定されていてもListBoxItem、ないMeasureOverrideに呼ばれています。

注:私はそのスクロールの設定は、このように自然に再でしょう、リストボックスの幅に合わせて、アイテムを強制しているため、予想通りMeasureOverrideが呼び出されるん、その場合には「無効」にScrollViewer.HorizontalScrollbarVisibilityを設定することでこれを回避することができます知っています-火災。しかし、私はまだWidthプロパティのメタデータにAffectsMeasureフラグが設定されており、幅がArrangeOverrideのステップで変更されているため、Measureがデフォルトで呼び出されない理由を理解しようとしています。

このフラグはそのコンテナのヒントに過ぎません。制御器がScrollViewerの場合は無視されますか?私が推測していることは、スクロールを無効にしない限り、コントロールは無限の領域を利用できるため、一度計測されると、再度計測する必要はないということです。水平スクロールを無効にすると、幅が無制限ではないことが示されているので、MeasureOverrideが再び呼び出されます。しかし、それは論理的なものですが、単なる推測です。

ここでは、再生するコード例を示します。新しいWPFプロジェクトを作成し、これをウィンドウのCodeBehindに貼り付け、デバッグ出力を確認します。次に、Horizo​​ntalScrollbarVisibilityフラグを設定すると、呼び出されることがわかります。

public partial class MainWindow : Window 
{ 
    public MainWindow(){ 
     InitializeComponent(); 
     var items = new List<object>(){ "This is a really, really, really, really long sentence"}; 
     var lbx = new ListBoxEx { ItemsSource = items }; 
     this.Content = lbx; 
    } 

} 

public class ListBoxEx : ListBox 
{ 
    protected override bool IsItemItsOwnContainerOverride(object item){ 
     return (item is ListBoxItemEx); 
    } 

    protected override DependencyObject GetContainerForItemOverride(){ 
     return new ListBoxItemEx(); 
    } 
} 

public class ListBoxItemEx : ListBoxItem 
{ 
    protected override Size MeasureOverride(Size availableSize){ 
     Console.WriteLine("MeasureOverride called with " + availableSize); 
     return base.MeasureOverride(availableSize); 
    } 

    protected override Size ArrangeOverride(Size finalSize){ 
     Console.WriteLine("ArrangeOverride called with " + finalSize); 
     return base.ArrangeOverride(finalSize); 
    } 

} 

答えて

0

[OK]を、私は答えは測定パスは、パネル、いない項目に影響を与えているので、それは発射いない、とその子を再測定する理由はありませんので、パネル自体のサイズを変更していないと思います。

ScrollViewer.HorizontalScrollbarVisibilityDisabledに設定すると、パネルの幅はその内容ではなくListBoxの幅を追跡するため、子供は再測定する必要があります。そのため、そのようになったのです。

関連する問題