滚动列表框WPF在代码视图模型设置的SelectedItem [英] Scroll WPF ListBox to the SelectedItem set in code in a view model

查看:137
本文介绍了滚动列表框WPF在代码视图模型设置的SelectedItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个列表框XAML视图:

 <控制:ListBoxScroll的ItemSource ={绑定路径= FooCollection }
的SelectedItem ={结合SelectedFoo,模式=双向}
ScrollSelectedItem ={结合SelectedFoo}>
<! - 数据模板等 - >
< /控制:ListBoxScroll>



选定的项目势必在我看来一个属性。当用户选择列表中的某个项目框在视图模型我SelectedFoo财产得到更新。当我设置在我看来模型,则正确的项目在列表框中选择的SelectedFoo属性。



现在的问题是,如果是在代码中设置的SelectedFoo不当前可见我需要另外拨打 ScrollIntoView 在列表框中。由于我的列表框是一个视图中,我的逻辑是我的看法模型中...我无法找到一个方便的方式来做到这一点。所以我延长ListBoxScroll:

 类ListBoxScroll:列表框
{
公共静态只读的DependencyProperty ScrollSelectedItemProperty =的DependencyProperty。寄存器(
ScrollSelectedItem,
的typeof(对象),
typeof运算(ListBoxScroll),
新FrameworkPropertyMetadata(
空,
FrameworkPropertyMetadataOptions.AffectsRender,
新PropertyChangedCallback(onScrollSelectedChanged)));
公共对象ScrollSelectedItem
{
{返回(对象)的GetValue(ScrollSelectedItemProperty); }
集合{的SetValue(ScrollSelectedItemProperty,值); }
}

私有静态无效onScrollSelectedChanged(DependencyObject的D,DependencyPropertyChangedEventArgs E)
{
变种列表框= D为ListBoxScroll;
listbox.ScrollIntoView(e.NewValue);
}
}



基本上,它暴露了一个新的依赖属性 ScrollSelectedItem 我绑定到我的视图模型的 SelectedFoo 属性。然后,我钩到属性改变了依赖属性的回调并滚动新选定的项目进入视野。



是否更简单的方法来调用用户控件功能,任何人都知道在由视图模型支持的XAML的看法?这是一个有点跑大约为:




  1. 创建一个依赖属性

  2. 添加一个回调属性更改回调

  3. 静态回调内把手函数调用



这将是很好把逻辑就在 ScrollSelectedItem {集合{方法,但将相关框架似乎偷偷摸摸和管理,而不实际调用它的工作。


< DIV CLASS =h2_lin>解决方案

审查应答后一个共同的主题上来:外部类听了ListBox的SelectionChanged事件。这使我认识到,依赖房地产的做法是矫枉过正,我可能只是有子类倾听本身:

 类ListBoxScroll :列表框
{
公共ListBoxScroll():基地()
{
的SelectionChanged + =新SelectionChangedEventHandler(ListBoxScroll_SelectionChanged);
}

无效ListBoxScroll_SelectionChanged(对象发件人,SelectionChangedEventArgs E)
{
ScrollIntoView(的SelectedItem);
}
}



我觉得这是最简单的解决方案,做什么,我想要的。



荣誉奖去adcool2007的抚养行为研究。这里有一对夫妇为那些有兴趣的文章:



http://blogs.msdn.com/b/johngossman/archive/2008/05/07/the-attached-behavior-pattern.aspx

http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx



我认为这将被添加到多个不同的用户控件的通用行为(如点击行为,拖拽行为,动画的行为,等等),那么附加的行为作出了很多感。我不想在这种特殊情况下使用它们的原因是该行为的实施(主叫 ScrollIntoView )是不是可以发生在任何控制常规操作除列表框等。


I have a XAML view with a list box:

<control:ListBoxScroll ItemSource="{Binding Path=FooCollection}"
                       SelectedItem="{Binding SelectedFoo, Mode=TwoWay}"
                       ScrollSelectedItem="{Binding SelectedFoo}">
    <!-- data templates, etc. -->
</control:ListBoxScroll>

The selected item is bound to a property in my view. When the user selects an item in the list box my SelectedFoo property in the view model gets updated. When I set the SelectedFoo property in my view model then the correct item is selected in the list box.

The problem is that if the SelectedFoo that is set in code is not currently visible I need to additionally call ScrollIntoView on the list box. Since my ListBox is inside a view and my logic is inside my view model ... I couldn't find a convenient way to do it. So I extended ListBoxScroll:

class ListBoxScroll : ListBox
{
    public static readonly DependencyProperty ScrollSelectedItemProperty = DependencyProperty.Register(
        "ScrollSelectedItem",
        typeof(object),
        typeof(ListBoxScroll),
        new FrameworkPropertyMetadata(
            null,
            FrameworkPropertyMetadataOptions.AffectsRender, 
            new PropertyChangedCallback(onScrollSelectedChanged)));
    public object ScrollSelectedItem
    {
        get { return (object)GetValue(ScrollSelectedItemProperty); }
        set { SetValue(ScrollSelectedItemProperty, value); }
    }

    private static void onScrollSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var listbox = d as ListBoxScroll;
        listbox.ScrollIntoView(e.NewValue);
    }
}

It basically exposes a new dependency property ScrollSelectedItem which I bind to the SelectedFoo property on my view model. I then hook into the property changed callback of the dependent property and scroll the newly selected item into view.

Does anyone else know of an easier way to call functions on user controls on a XAML view that is backed by a view model? It's a bit of a run around to:

  1. create a dependent property
  2. add a callback to the property changed callback
  3. handle function invocation inside the static callback

It would be nice to put the logic right in the ScrollSelectedItem { set { method but the dependency framework seems to sneak around and manages to work without actually calling it.

解决方案

After reviewing the answers a common theme came up: external classes listening to the SelectionChanged event of the ListBox. That made me realize that the dependant property approach was overkill and I could just have the sub-class listen to itself:

class ListBoxScroll : ListBox
{
    public ListBoxScroll() : base()
    {
        SelectionChanged += new SelectionChangedEventHandler(ListBoxScroll_SelectionChanged);
    }

    void ListBoxScroll_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ScrollIntoView(SelectedItem);
    }
}

I feel this is the simplest solution that does what I want.

Honourable mention goes to adcool2007 for bringing up Behaviours. Here are a couple of articles for those interested:

http://blogs.msdn.com/b/johngossman/archive/2008/05/07/the-attached-behavior-pattern.aspx
http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx

I think for generic behaviours that will be added to several different user controls (e.g. click behaviours, drag behaviours, animation behaviours, etc.) then attached behaviours make a lot of sense. The reason I don't want to use them in this particular case is that the implementation of the behaviour (calling ScrollIntoView) isn't a generic action that can happen to any control other than a ListBox.

这篇关于滚动列表框WPF在代码视图模型设置的SelectedItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆