如何移动到 WPF Listbox 的顶部?

huangapple go评论65阅读模式
英文:

How to move to the top of a WPF Listbox?

问题

我在一个.xaml文件中有一个可滚动的ListBox,它绑定到一个视图模型中的可观察集合。

当新数据添加到集合中时,该数据会添加到ListBox的顶部。当ListBox包含大量数据并且我向下滚动ListBox时,新数据会添加到其顶部,但除非我使用滚动条滚动到顶部,否则我看不到它。
每次向可观察集合添加新项后,如何自动滚动到顶部?

WPF代码:

<ListBox Grid.Row="2"
         Grid.Column="0"
         ItemsSource="{Binding BagItems}"
         ItemTemplateSelector="{StaticResource BagItemTemplateSelector}"
         Grid.ColumnSpan="5"
         Foreground="{DynamicResource DarkerGreyBrush}"
         Background="{DynamicResource LightestGreyBrush}"
         FontWeight="Medium"
         HorizontalContentAlignment="Stretch"
         ItemContainerStyle="{DynamicResource ListBoxContainerStyle}"
         SelectedItem="{Binding SelectedItem}" 
         ScrollViewer.HorizontalScrollBarVisibility="Disabled"
         KeyDown="ListBox_KeyDown" ManipulationBoundaryFeedback="ListBox_ManipulationBoundaryFeedback">
    <i:Interaction.Behaviors>
        <behaviours:ListBoxSelectionModeOverrideBehaviour SupressKeyEvents="{Binding DialogController.DialogAvailable}" />
    </i:Interaction.Behaviors>
</ListBox>

视图模型C#代码:

if (shoppingBagItem != null)
{
    this.TryInvokeOnUiThread(() =>
    {
        this.BagItems.Insert(0, shoppingBagItem);
        this.SelectedItem = shoppingBagItem;
    });
}
英文:

I've got a scrollable ListBox in a .xaml file that's bound to some data - an observable collection in a view model.

When new data is added to the collection, that data gets added to the top of the ListBox. When the ListBox contains lots of data and I scroll down the ListBox, new data gets added to the top of it however I can't see it unless I use the scrollbar to scroll to the top.
How can I automatically scroll to the top after each new item is added to the observable collection?

WPF code:

        &lt;ListBox Grid.Row=&quot;2&quot;
                 Grid.Column=&quot;0&quot;
                 ItemsSource=&quot;{Binding BagItems}&quot;
                 ItemTemplateSelector=&quot;{StaticResource BagItemTemplateSelector}&quot;
                 Grid.ColumnSpan=&quot;5&quot;
                 Foreground=&quot;{DynamicResource DarkerGreyBrush}&quot;
                 Background=&quot;{DynamicResource LightestGreyBrush}&quot;
                 FontWeight=&quot;Medium&quot;
                 HorizontalContentAlignment=&quot;Stretch&quot;
                 ItemContainerStyle=&quot;{DynamicResource ListBoxContainerStyle}&quot;
                 SelectedItem=&quot;{Binding SelectedItem}&quot; 
                 ScrollViewer.HorizontalScrollBarVisibility=&quot;Disabled&quot;
                 KeyDown=&quot;ListBox_KeyDown&quot; ManipulationBoundaryFeedback=&quot;ListBox_ManipulationBoundaryFeedback&quot;&gt;
            &lt;i:Interaction.Behaviors&gt;
                &lt;behaviours:ListBoxSelectionModeOverrideBehaviour SupressKeyEvents=&quot;{Binding DialogController.DialogAvailable}&quot; /&gt;
            &lt;/i:Interaction.Behaviors&gt;
        &lt;/ListBox&gt;

View model C# code:

if (shoppingBagItem != null)
{
	this.TryInvokeOnUiThread(() =&gt;
	{
		this.BagItems.Insert(0, shoppingBagItem);
		this.SelectedItem = shoppingBagItem;
	});
}

答案1

得分: 1

以下是已翻译的内容:

以下的 Behavior 类会自动将 ListBox 中的 SelectedItem 滚动到视图中。

public class perListBoxHelper : Behavior<ListBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
    }

    private static void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var listBox = sender as ListBox;

        if (listBox == null)
        {
            return;
        }

        Action action = () =>
        {
            var selectedItem = listBox.SelectedItem;

            if (selectedItem != null)
            {                    
                listBox.ScrollIntoView(selectedItem);
            }
        };

        listBox.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
    }
}

用法...

<ListBox ... >
    <i:Interaction.Behaviors>
        <vhelp:perListBoxScrollSelecionIntoViewBehavior />
    </i:Interaction.Behaviors>
</ListBox>

更多详情请查看我的博客文章

英文:

The following Behavior class will automaticaly scroll the SelectedItem of a ListBox into view.

public class perListBoxHelper : Behavior&lt;ListBox&gt;
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
    }

    private static void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var listBox = sender as ListBox;

        if (listBox == null)
        {
            return;
        }

        Action action = () =&gt;
        {
            var selectedItem = listBox.SelectedItem;

            if (selectedItem != null)
            {                    
                listBox.ScrollIntoView(selectedItem);
            }
        };

        listBox.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
    }
}

Useage ...

&lt;ListBox ... &gt;
    &lt;i:Interaction.Behaviors&gt;
        &lt;vhelp:perListBoxScrollSelecionIntoViewBehavior /&gt;
    &lt;/i:Interaction.Behaviors&gt;
&lt;/ListBox&gt;

More details on my blog post.

huangapple
  • 本文由 发表于 2023年5月24日 22:03:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76324397.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定