Сохранение позиции прокрутки при обновлении ItemSource сетки данных silverlight - PullRequest
1 голос
/ 03 декабря 2009

Я использую DataGrid в своем приложении silverlight для отображения некоторых данных, которые обновляются по таймеру. Моя проблема в том, что когда это происходит, вертикальная полоса прокрутки в сетке сбрасывается в верхнюю часть, тогда как я хочу, чтобы она оставалась в той же позиции. Кто-нибудь знает, как я могу это сделать?

Я попытался переопределить свойство ItemsSource в сетке, чтобы сохранить положение вертикальной прокрутки, а затем сбросить его, но это влияет только на полосу прокрутки и не заставляет отображаться правильные строки. Есть ли способ заставить это поведение?

Ответы [ 5 ]

2 голосов
/ 04 декабря 2009

Вот аналогичный вопрос о настройке положения полосы прокрутки в ListBox

После повторного связывания элемента управления Silverlight Listbox как получить список со списком для прокрутки к началу?

Поскольку DataGrid также поддерживает метод ScrollIntoView, вы должны иметь возможность использовать подобную технику, например

theDataGrid.ItemsSource = data; 
theDataGrid.UpdateLayout(); 
theDataGrid.ScrollIntoView(theDataGrid.SelectedItem, theDataGrid.Columns[0]);
1 голос
/ 16 декабря 2009

Я не мог найти приличный ответ в прошлый раз, когда я смотрел. Я хотел оставить текущий элемент выбранным в сетке, но он не будет работать при обновлении ICollectionView (я использую MVVM и получаю автоматические обновления с сервера).

ScrollIntoView() не был для меня вариантом, потому что выбранный в данный момент элемент НЕ может быть виден. Возникновение события CurrentChanged из-под контроля также было довольно проблематично.

В конце концов, я использовал сетку Infragistics, и она делает это из коробки. Проблема решена для меня.

Вы можете взглянуть на бесплатную сетку DevExpress. Я думаю, что у него было такое же хорошее поведение (я проверял это, но я не могу вспомнить результат).

0 голосов
/ 03 января 2011

Я изменил решение CodeMaster, чтобы вам не нужна переменная уровня класса. Поместите этот код в метод, который обновляет ItemsSource. Он будет динамически создавать обработчик событий, присоединять его, а затем отсоединять.

EventHandler MyDataGrid_LayoutUpdated = null;

MyDataGrid_LayoutUpdated = (s, e) =>
    {
        MyDataGrid.ScrollIntoView(dataItem, MyDataGrid.Columns[0]);
        MyDataGrid.LayoutUpdated -= MyDataGrid_LayoutUpdated;
    };

MyDataGrid.LayoutUpdated += MyDataGrid_LayoutUpdated;
0 голосов
/ 08 декабря 2009

У меня тоже были проблемы с этим. Я решил это, вспомнив элемент, к которому я хочу прокрутить, а затем заново связал DataGrid. Я обрабатываю событие LayoutUpdated для реализации желаемой функциональности:

void MyDataGrid_LayoutUpdated(object sender, EventArgs e)
    {
        // Reference the data item in the list you want to scroll to.
        object dataItem = yourDataItem;

        // Make sure the item is not null and didn't already scroll to the item.
        if (dataItem != null && this.dataItemScrolledTo != dataItem)
        {
            // Remember the item scrolled to.
            this.dataItemScrolledTo = dataItem;

            // Scroll datagrid to the desired item.
            MyDataGrid.ScrollIntoView(dataItem, MyDataGrid.Columns[0]);
        }
    }
0 голосов
/ 04 декабря 2009

Вы можете попробовать установить SelectedItem через поток пользовательского интерфейса, чтобы пользовательский интерфейс мог обновляться сам, вот так

private void Button_Click(object sender, RoutedEventArgs e)
    {
        Person p = new Person() { Name="sss",Age=11};  //datagird's itemsSource is Collection<person>
        people.Add(p);
        dg.SelectedItem = p;  //dg is my datagrid name
        Dispatcher.BeginInvoke(() => { dg.SelectedItem = p; });
    }

Я предполагаю, что через ViewModel загружаются новые строки, поэтому имеет смысл поместить туда BeginInvoke. Поскольку операции ViewModel выполняются в другом потоке, и простая установка SelectedItem самостоятельно может не сработать, это сработало для кого-то другого

...