gpt4 book ai didi

wpf - 如何使用 caliburn.micro 从 View 模型设置滚动位置?

转载 作者:行者123 更新时间:2023-12-03 10:55:30 26 4
gpt4 key购买 nike

我有一个 ListBox在我看来,绑定(bind)到一个动态增长的集合。我希望滚动位置跟随最后添加的项目(附加到列表底部)。如何使用 Caliburn.Micro 实现这一目标?

最佳答案

另一种方法是使用事件聚合器将消息发布到 View 。

就像是:

Aggregator.Publish(ItemAddedMessage<SomeItemType>(itemThatWasJustAdded));

在 View 中:
public class SomeView : IHandle<ItemAddedMessage<SomeItemType>>
{

public void Handle(ItemAddedMessage<SomeItemType> message)
{
// Implement view specific behaviour here
}
}

这取决于您的要求,但至少 View 负责显示问题,您仍然可以测试 VM

您也可以只在 View 中实现代码 - 因为它似乎是一个 View 问题(例如,使用列表框提供的事件)

一种行为也会很有用,但可能与您的类型的耦合度较低 - 例如通用行为 SeekAddedItemBehaviour它 Hook 列表框事件以查找最后一项。不确定列表框是否公开了所需的事件,但值得一看

编辑:

好的,这可能会完全停止 - 你应该能够将此行为附加到列表框,它应该负责其余的:
public class ListBoxSeekLastItemBehaviour : System.Windows.Interactivity.Behavior<ListBox>
{
private static readonly DependencyProperty ItemsSourceWatcherProperty = DependencyProperty.Register("ItemsSourceWatcher", typeof(object), typeof(ListBoxSeekLastItemBehaviour), new PropertyMetadata(null, OnItemsSourceWatcherPropertyChanged));

private ListBox _listBox = null;

private static void OnItemsSourceWatcherPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ListBoxSeekLastItemBehaviour source = d as ListBoxSeekLastItemBehaviour;

if (source != null)
source.OnItemsSourceWatcherPropertyChanged();
}

private void OnItemsSourceWatcherPropertyChanged()
{
// The itemssource has changed, check if it raises collection changed notifications
if (_listBox.ItemsSource is INotifyCollectionChanged)
{
// if it does, hook the CollectionChanged event so we can respond to items being added
(_listBox.ItemsSource as INotifyCollectionChanged).CollectionChanged += new NotifyCollectionChangedEventHandler(ListBoxSeekLastItemBehaviour_CollectionChanged);
}
}

void ListBoxSeekLastItemBehaviour_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems.Count > 0)
{
// If an item was added seek it
ScrollIntoView(e.NewItems[0]);
}
}

protected override void OnAttached()
{
base.OnAttached();

// We've been attached - get the associated listbox
var box = this.AssociatedObject as ListBox;

if (box != null)
{
// Hold a ref
_listBox = box;

// Set a binding to watch for property changes
System.Windows.Data.Binding binding = new System.Windows.Data.Binding("ItemsSource") { Source = _listBox; }

// EDIT: Potential bugfix - you probably want to check the itemssource here just
// in case the behaviour is applied after the original ItemsSource binding has been evaluated - otherwise you might miss the change
OnItemsSourceWatcherPropertyChanged();
}
}

private void ScrollIntoView(object target)
{
// Set selected item and try and scroll it into view
_listBox.SelectedItem = target;
_listBox.ScrollIntoView(target);
}
}

您可能想稍微整理一下,并确保 CollectionChanged 的事件处理程序当 ItemsSource 被删除变化。

你也可以叫它 SeekLastAddedItemBehaviourSeekLastAddedItemBehavior - 我倾向于保留美式拼写,因为它与 Microsoft 的拼写匹配。我认为 SeekLastItem听起来它会滚动到列表中的最后一项而不是最后添加的项目

关于wpf - 如何使用 caliburn.micro 从 View 模型设置滚动位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15281804/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com