7

ListBox一番上までスクロールして、リストの最初の項目をユーザーに表示できるように、最初のレンダリングがいつ終了したかを知る必要があります。

私はそれListBoxで使用するを持っています:RichTextBoxDataTemplate

<DataTemplate x:Key="HelpTextTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        ...
        <ContentControl>
            ...
            <RichTextBox x:Name="HelpTextContent" Grid.Row="1"
                         Tag="{Binding Path=HelpObject.Text, Mode=TwoWay}"
                         TextWrapping="Wrap"
                         HorizontalAlignment="Stretch"
                         Margin="0,0,20,0"
                         Loaded="RichTextBox_Loaded"
                         ContentChanged="RichTextBox_ContentChanged"
                         SelectionChanged="RichTextBox_SelectionChanged"/>
            ...
        </ContentControl>
        ...
    </Grid>
</DataTemplate>

ListBoxにバインドされていObservableCollectionます。

のスクロールに問題がありましたListBox- の高さがユーザーの高さRichTextBoxよりも大きい場合、ListBoxの一番下までスクロールできませんでしたRichTextBox。リスト内の次のListBox項目にジャンプします。スクロール バーのスライダーの高さも変更されます。これは、 の実際の高さは、RichTextBox実際にレンダリングされたときにのみ計算されるためです。画面から外れると、高さはより小さな値に戻ります (コードは、テキストを折り返すのではなく、すべて 1 行に収めることができると想定していると思います)。

これらの問題は、 がアイテムを描画するために をListBox使用することまで突き止めました。VirtualisingStackPanelそれを単純なものに置き換えると、StackPanelそれらの問題はなくなりました。

これにより、ListBox初期ロード時にリストの一番下までスクロールするという問題が発生しました。LoadedおよびLayoutUpdatedイベントは、ListBoxデータがロードされる前に発生します。PropertyChangedが初期化されたときに、ビューモデルでイベントをリッスンしようとしましたObservableCollection:

void editViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    switch (e.PropertyName)
    {
        case "ListDataSource":
            // Try to scroll to the top of the ListBox
            break;
    }
}

これも発火が早すぎます。このイベントが発生した後にリストがレンダリングされListBox、 が一番下までスクロールします。

4

3 に答える 3

0
public class AutoScrollBehavior : Behavior<ListBox>
    {
        #region Properties

        public object ItemToScroll
        {
            get { return GetValue(ItemToScrollProperty); }
            set { SetValue(ItemToScrollProperty, value); }
        }

        public static readonly DependencyProperty ItemToScrollProperty = DependencyProperty.Register("ItemToScroll", typeof(object), typeof(AutoScrollBehavior), new PropertyMetadata(ItemToScrollPropertyChanged));

        private static void ItemToScrollPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ListBox lb = ((AutoScrollBehavior)d).AssociatedObject;
            lb.UpdateLayout();
            ((AutoScrollBehavior)d).AssociatedObject.ScrollIntoView(e.NewValue);
        }
        #endregion
    }

次に、XAMLで次のように使用します

<ListBox SelectedItem="{Binding SelectedItemFromModel, Mode=TwoWay}">
<i:Interaction.Behaviors>
                                                                <Behaviors:AutoScrollBehavior ItemToScroll="{Binding SelectedItemFromModel}"/>
                                                            </i:Interaction.Behaviors>
</ListBox>

一部のコマンドでは、ビューモデルのSelectedItemFromModelプロパティを制御および設定できる必要があります。

于 2012-11-15T16:07:06.427 に答える
0

Loaded ハンドラーをスクロールしようとしますが、Dispatcher によって少し遅れます。そんな感じ

void OnLoaded(...)
{
   Dispatcher.BeginInvoke(() => {/*Scroll your ListBox here*/});
}

それは役立つかもしれません。

于 2012-07-06T21:39:33.090 に答える