私はListBoxItem
のサブクラスとListBox
のサブクラスを作成しました。これはIsItemItsOwnContainerOverride
とGetContainerForItemOverride
の両方をオーバーライドしてコンテナとして使用します。幅が変更されたときにListBoxItemがMeasureOverrideを呼び出さないのはなぜですか?
ここで、ウィンドウが最初に表示されたら、ListBoxItem
(Infinity、Infinityで)ごとにMeasureOverride
が呼び出され、その後すべての項目でArrangeOverride
が呼び出されます。
ListBox
のサイズを変更する際しかし、唯一ArrangeOverride
は、widthプロパティのメタデータがAffectsMeasure
に設定されていてもListBoxItem
、ないMeasureOverride
に呼ばれています。
注:私はそのスクロールの設定は、このように自然に再でしょう、リストボックスの幅に合わせて、アイテムを強制しているため、予想通り
MeasureOverride
が呼び出されるん、その場合には「無効」にScrollViewer.HorizontalScrollbarVisibility
を設定することでこれを回避することができます知っています-火災。しかし、私はまだWidth
プロパティのメタデータにAffectsMeasure
フラグが設定されており、幅がArrangeOverride
のステップで変更されているため、Measureがデフォルトで呼び出されない理由を理解しようとしています。
このフラグはそのコンテナのヒントに過ぎません。制御器がScrollViewer
の場合は無視されますか?私が推測していることは、スクロールを無効にしない限り、コントロールは無限の領域を利用できるため、一度計測されると、再度計測する必要はないということです。水平スクロールを無効にすると、幅が無制限ではないことが示されているので、MeasureOverride
が再び呼び出されます。しかし、それは論理的なものですが、単なる推測です。
ここでは、再生するコード例を示します。新しいWPFプロジェクトを作成し、これをウィンドウのCodeBehindに貼り付け、デバッグ出力を確認します。次に、HorizontalScrollbarVisibilityフラグを設定すると、呼び出されることがわかります。
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);
}
}