首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ItemContainerGenerator.ContainerFromItem如何处理分组列表?

ItemContainerGenerator.ContainerFromItem如何处理分组列表?
EN

Stack Overflow用户
提问于 2008-10-03 02:22:07
回答 3查看 27.8K关注 0票数 30

我有一个ListBox,直到最近它还在显示项目的平面列表。我能够使用myList.ItemContainerGenerator.ConainerFromItem(thing)检索列表中的ListBoxItem托管“东西”。

本周,我略微修改了ListBox,因为它绑定到的条目的CollectionViewSource启用了分组。现在,ListBox中的项被分组到漂亮的标题下。

然而,自从这样做后,ItemContainerGenerator.ContainerFromItem停止了工作-即使我知道ListBox中的项,它也会返回null。见鬼-即使ListBox填充了很多项,ContainerFromIndex(0)也会返回null!

如何从显示分组项的ListBoxItem中检索ListBox?

编辑:下面是一个精简示例的XAML和代码分离。这会引发一个NullReferenceException,因为即使列表中有四个项目,ContainerFromIndex(1)也会返回null。

XAML:

代码语言:javascript
复制
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
    Title="Window1">

    <Window.Resources>
        <XmlDataProvider x:Key="myTasks" XPath="Tasks/Task">
            <x:XData>
                <Tasks xmlns="">
                    <Task Name="Groceries" Type="Home"/>
                    <Task Name="Cleaning" Type="Home"/>
                    <Task Name="Coding" Type="Work"/>
                    <Task Name="Meetings" Type="Work"/>
                </Tasks>
            </x:XData>
        </XmlDataProvider>

        <CollectionViewSource x:Key="mySortedTasks" Source="{StaticResource myTasks}">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="@Type" />
                <scm:SortDescription PropertyName="@Name" />
            </CollectionViewSource.SortDescriptions>

            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="@Type" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>

    <ListBox 
        x:Name="listBox1" 
        ItemsSource="{Binding Source={StaticResource mySortedTasks}}" 
        DisplayMemberPath="@Name"
        >
        <ListBox.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}"/>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ListBox.GroupStyle>
    </ListBox>
</Window>

政务司司长:

代码语言:javascript
复制
public Window1()
{
    InitializeComponent();
    listBox1.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
}

void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
    if (listBox1.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
    {
        listBox1.ItemContainerGenerator.StatusChanged -= ItemContainerGenerator_StatusChanged;

        var i = listBox1.ItemContainerGenerator.ContainerFromIndex(1) as ListBoxItem;

        // select and keyboard-focus the second item
        i.IsSelected = true;
        i.Focus();
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2008-10-03 22:21:58

您可以使用侦听ItemsGenerator.StatusChanged事件并对其做出反应,并等到生成ItemContainers后才能使用ContainerFromElement访问它们。

进一步搜索,我找到了某个有同样问题的人的a thread in the MSDN forum。这似乎是WPF中的一个错误,当一个人有一个GroupStyle设置。解决方案是在渲染过程之后平移ItemGenerator的访问。以下是您的问题的代码。我试过了,它起作用了:

代码语言:javascript
复制
    void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
    {
        if (listBox1.ItemContainerGenerator.Status
            == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
        {
            listBox1.ItemContainerGenerator.StatusChanged
                -= ItemContainerGenerator_StatusChanged;
            Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input,
                new Action(DelayedAction));
        }
    }

    void DelayedAction()
    {
        var i = listBox1.ItemContainerGenerator.ContainerFromIndex(1) as ListBoxItem;

        // select and keyboard-focus the second item
        i.IsSelected = true;
        i.Focus();
    }
票数 40
EN

Stack Overflow用户

发布于 2014-05-12 20:15:31

如果上面的代码不适用于您,请尝试以下代码

代码语言:javascript
复制
public class ListBoxExtenders : DependencyObject
{
    public static readonly DependencyProperty AutoScrollToCurrentItemProperty = DependencyProperty.RegisterAttached("AutoScrollToCurrentItem", typeof(bool), typeof(ListBoxExtenders), new UIPropertyMetadata(default(bool), OnAutoScrollToCurrentItemChanged));

    public static bool GetAutoScrollToCurrentItem(DependencyObject obj)
    {
        return (bool)obj.GetValue(AutoScrollToSelectedItemProperty);
    }

    public static void SetAutoScrollToCurrentItem(DependencyObject obj, bool value)
    {
        obj.SetValue(AutoScrollToSelectedItemProperty, value);
    }

    public static void OnAutoScrollToCurrentItemChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
    {
        var listBox = s as ListBox;
        if (listBox != null)
        {
            var listBoxItems = listBox.Items;
            if (listBoxItems != null)
            {
                var newValue = (bool)e.NewValue;

                var autoScrollToCurrentItemWorker = new EventHandler((s1, e2) => OnAutoScrollToCurrentItem(listBox, listBox.Items.CurrentPosition));

                if (newValue)
                    listBoxItems.CurrentChanged += autoScrollToCurrentItemWorker;
                else
                    listBoxItems.CurrentChanged -= autoScrollToCurrentItemWorker;
            }
        }
    }

    public static void OnAutoScrollToCurrentItem(ListBox listBox, int index)
    {
        if (listBox != null && listBox.Items != null && listBox.Items.Count > index && index >= 0)
            listBox.ScrollIntoView(listBox.Items[index]);
    }

}

XAML中的用法

代码语言:javascript
复制
<ListBox IsSynchronizedWithCurrentItem="True" extenders:ListBoxExtenders.AutoScrollToCurrentItem="True" ..../>
票数 2
EN

Stack Overflow用户

发布于 2008-10-03 02:25:48

尝试从'thing‘开始向上解析VisualTree,直到到达ListBoxItem类型

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/165424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档