Ссылка на ячейку, являющаяся ссылкой, работает в обоих направлениях - если вы измените свой выбор, номер в ячейке изменится, а если вы измените номер в ячейке, выделенный выбор изменится.

тоящее время у меня есть ListBox, чья коллекция ItemsSource связана со свойством в моей модели представления, типа IEnumerable. При изменении ссылки этого preoprty, ListBox обновляется, как и ожидалось, однако у меня есть проблема в том, что если у меня есть большая коллекция элементов и прокрутите до нижней части ListBox, а затем изменить ссылку на другую коллекцию, содержащую, скажем, 1 элемент представление ListBox пустое и полоса прокрутки не отображается. Затем я должен прокрутить список с помощью колесика мыши, пока не появится 1 элемент.

Итак, я думаю, что мне нужно, это способ сброса позиции прокрутки ListBox вверх при каждом изменении свойства ItemsSource, так, чтобы что-то всегда отображалось независимо от того, большой или маленький набор.

 Fredrik Hedblad26 янв. 2011 г., 13:35
Правильно ли я понял ваш вопрос или вы искали что-то еще?
 devdigital26 янв. 2011 г., 18:11
Нашел ответ наsocial.msdn.microsoft.com/Forums/en/wpf/thread/... для VirtualizingTilePanel, но я перешел на виртуализационную оболочку из двоичной передачи -binarymission.co.uk/binaryvirtwrappanelsl3.htm
 devdigital26 янв. 2011 г., 14:12
@ Meleak Спасибо! такой подход будет полезен. Я на самом деле отследил проблему до VirtualizingTilePanel, который использует мой ListBox, который я взял изblogs.msdn.com/b/dancre/archive/2006/02/16/..., Проблема может быть воспроизведена при загрузке примера путем прокрутки вниз, а затем замены связанной коллекции на коллекцию, содержащую один элемент. Вид гаснет, пока вы не прокрутите колесо мыши вверх.

Ответы на вопрос(5)

вы выбираете диапазон ячеек в качестве вариантов выбора, которые затем перечисляются в списке. Вы также выбираете ячейку в качестве ссылки на выбранные варианты, в которых число будет отображаться в зависимости от позиции выбора в списке. 1 для первого в списке, 2 для второго и т. Д. Код довольно прост:

Range ( "A1") Выбрать

Выбор = 1

Измените («A1») на ячейку, которую вы связали, и измените 1 на позицию в списке, который вы хотите выбрать.

Ссылка на ячейку, являющаяся ссылкой, работает в обоих направлениях - если вы измените свой выбор, номер в ячейке изменится, а если вы измените номер в ячейке, выделенный выбор изменится.

public static class ItemsControlAttachedProperties
{
    #region ScrollToTopOnItemsSourceChange Property

    public static readonly DependencyProperty ScrollToTopOnItemsSourceChangeProperty =
        DependencyProperty.RegisterAttached(
            "ScrollToTopOnItemsSourceChange",
            typeof(bool),
            typeof(ItemsControlAttachedProperties),
            new UIPropertyMetadata(false, OnScrollToTopOnItemsSourceChangePropertyChanged));

    public static bool GetScrollToTopOnItemsSourceChange(DependencyObject obj)
    {
        return (bool) obj.GetValue(ScrollToTopOnItemsSourceChangeProperty);
    }

    public static void SetScrollToTopOnItemsSourceChange(DependencyObject obj, bool value)
    {
        obj.SetValue(ScrollToTopOnItemsSourceChangeProperty, value);
    }

    static void OnScrollToTopOnItemsSourceChangePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var itemsControl = obj as ItemsControl;
        if (itemsControl == null)
        {
            throw new Exception("ScrollToTopOnItemsSourceChange Property must be attached to an ItemsControl based control.");
        }

        DependencyPropertyDescriptor descriptor =
            DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(ItemsControl));
        if (descriptor != null)
        {
            if ((bool) e.NewValue)
            {
                descriptor.AddValueChanged(itemsControl, ItemsSourceChanged);
            }
            else
            {
                descriptor.RemoveValueChanged(itemsControl, ItemsSourceChanged);
            }
        }
    }

    static void ItemsSourceChanged(object sender, EventArgs e)
    {
        var itemsControl = sender as ItemsControl;
        DoScrollToTop(itemsControl);

        var collection = itemsControl.ItemsSource as INotifyCollectionChanged;
        if (collection != null)
        {
            collection.CollectionChanged += (o, args) => DoScrollToTop(itemsControl);
        }
    }

    static void DoScrollToTop(ItemsControl itemsControl)
    {
        EventHandler eventHandler = null;
        eventHandler =
            delegate
            {
                if (itemsControl.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
                {
                    var scrollViewer = GetVisualChild<ScrollViewer>(itemsControl);
                    scrollViewer.ScrollToTop();
                    itemsControl.ItemContainerGenerator.StatusChanged -= eventHandler;
                }
            };
        itemsControl.ItemContainerGenerator.StatusChanged += eventHandler;
    }

    static T GetVisualChild<T>(DependencyObject parent) where T : Visual
    {
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (var i = 0; i < numVisuals; i++)
        {
            var v = (Visual) VisualTreeHelper.GetChild(parent, i);
            child = v as T ?? GetVisualChild<T>(v);
            if (child != null)
            {
                break;
            }
        }
        return child;
    }

    #endregion
}
Решение Вопроса

ListBox прокручивается до последнего элемента в новой коллекции при измененииItemsSource). Во всяком случае, чтобы прокрутитьListBox на вершину каждый раз, когда егоItemsSource изменения вы можете использовать некоторый код позади. Сначала послушайте изменения вItemsSourceProperty а затем прокрутитеListBox наверх, как только его элементы были созданы

Обновить

Сделал прикрепленное поведение, которое делает это, чтобы избежать кода позади. Это можно использовать так

<ListBox ...
         behaviors:ScrollToTopBehavior.ScrollToTop="True"/>

ScrollToTopBehavior

public static class ScrollToTopBehavior 
{
    public static readonly DependencyProperty ScrollToTopProperty = 
        DependencyProperty.RegisterAttached 
        (
            "ScrollToTop", 
            typeof(bool),
            typeof(ScrollToTopBehavior),
            new UIPropertyMetadata(false, OnScrollToTopPropertyChanged) 
        );
    public static bool GetScrollToTop(DependencyObject obj) 
    {
        return (bool)obj.GetValue(ScrollToTopProperty); 
    }
    public static void SetScrollToTop(DependencyObject obj, bool value) 
    {
        obj.SetValue(ScrollToTopProperty, value); 
    }
    private static void OnScrollToTopPropertyChanged(DependencyObject dpo, 
                                                     DependencyPropertyChangedEventArgs e) 
    {
        ItemsControl itemsControl = dpo as ItemsControl;
        if (itemsControl != null) 
        {
            DependencyPropertyDescriptor dependencyPropertyDescriptor =
                    DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(ItemsControl));
            if (dependencyPropertyDescriptor != null)
            {
                if ((bool)e.NewValue == true) 
                {
                    dependencyPropertyDescriptor.AddValueChanged(itemsControl, ItemsSourceChanged);
                }
                else 
                {
                    dependencyPropertyDescriptor.RemoveValueChanged(itemsControl, ItemsSourceChanged);
                }
            } 
        } 
    }
    static void ItemsSourceChanged(object sender, EventArgs e)
    {
        ItemsControl itemsControl = sender as ItemsControl;
        EventHandler eventHandler = null;
        eventHandler = new EventHandler(delegate
        {
            if (itemsControl.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
            {
                ScrollViewer scrollViewer = GetVisualChild<ScrollViewer>(itemsControl) as ScrollViewer;
                scrollViewer.ScrollToTop();
                itemsControl.ItemContainerGenerator.StatusChanged -= eventHandler;
            }
        });
        itemsControl.ItemContainerGenerator.StatusChanged += eventHandler;
    }
}

И реализация GetVisualChild

private T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
    T child = default(T);
    int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < numVisuals; i++)
    {
        Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null)
        {
            child = GetVisualChild<T>(v);
        }
        if (child != null)
        {
            break;
        }
    }
    return child;
}
 Mohini Mhetre15 февр. 2016 г., 10:23
это было действительно полезно :)

Поздний ответ:

Простое решение - добавить обработчик событий дляTargetUpdated событие и установитьNotifyOnTargetUpdated=True наItemsSource связывание:

<ListBox x:Name="listBox" 
         ItemsSource="{Binding MySource, NotifyOnTargetUpdated=True}"
         TargetUpdated="ListBox_TargetUpdated"/>

и в обработчике событий выделите верхний элемент:

private void ListBox_TargetUpdated(object sender, DataTransferEventArgs e)
{
    if (listBox.Items.Count > 0)
    {
        listBox.ScrollIntoView(listBox.Items[0]);
    }
}

Попробуй это:

if (listBox.Items.Count > 0) {
    listBox.ScrollIntoView(listBox.Items[0]); 
}

Ваш ответ на вопрос