Прокрутите WPF Listview к определенной строке

В вашем коде я вижу две ключевые проблемы:

void itov(char vigesimalStr[])
// ...
    return -1;

Функция itov() не может быть void, если она возвращает -1 при ошибке. Он также не может вернуть правильное значение в случае успеха!

for (int j = length; j >= 0; j--)

При запуске последовательности в обратном направлении вы хотите начать с length - 1, так как само length никогда не является допустимым индексом, поскольку это последний индекс плюс один.

Ниже доработка вашего кода с устранением вышеуказанных проблем и устранением других мелких проблем:

#include <stdio.h>
#include <stdlib.h>

#define BASE 20

int val(char c)
{
    if ('0' <= c && c <= '9')
        return c - '0';

    return c - 'A' + 10;
}

int itov(char vigesimalStr[])
{
    int length = 0;

    for (length = 0; vigesimalStr[length] != '\0'; length++)
    {
        // nothing to see here
    }

    int power = 1;
    int number = 0;

    for (int j = length - 1; j >= 0; j--)
    {
        int digit = val(vigesimalStr[j]);

        if (digit >= BASE)
        {
            fprintf(stderr, "Invalid Number\n");
            return -1;
        }

        number += digit * power;
        power *= BASE;
    }

    return number;
}

int main()
{
    char to_convert[20] = "1A";

    printf("%d\n", itov(to_convert));

    return 0;
}
22
задан Sam 17 October 2008 в 13:34
поделиться

6 ответов

Я думаю, что проблема здесь состоит в том, что ListViewItem еще не создается, если строка не видима. WPF создает Видимое по требованию.

Так в этом случае Вы, вероятно, добираетесь null для объекта, не так ли? (Согласно Вашему комментарию, Вы делаете)

, я нашел ссылка на форумы MSDN, которые предлагают получить доступ к Scrollviewer непосредственно для прокрутки. Мне решение, представленное там, очень походит на взлом, но можно решить для себя.

Вот фрагмент кода от эти ссылка выше :

VirtualizingStackPanel vsp =  
  (VirtualizingStackPanel)typeof(ItemsControl).InvokeMember("_itemsHost",
   BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic, null, 
   _listView, null);

double scrollHeight = vsp.ScrollOwner.ScrollableHeight;

// itemIndex_ is index of the item which we want to show in the middle of the view
double offset = scrollHeight * itemIndex_ / _listView.Items.Count;

vsp.SetVerticalOffset(offset);
10
ответ дан 29 November 2019 в 03:44
поделиться

Кто-то сказал мне еще лучший способ прокрутить к определенной строке, которая легка и работает как очарование.
Короче говоря:

public void ScrollToLastItem()
{
  lv.SelectedItem = lv.Items.GetItemAt(rows.Count - 1);
  lv.ScrollIntoView(lv.SelectedItem);
  ListViewItem item = lv.ItemContainerGenerator.ContainerFromItem(lv.SelectedItem) as ListViewItem;
  item.Focus();
}

более длительная версия в форумы MSDN :

39
ответ дан 29 November 2019 в 03:44
поделиться

Одно обходное решение к этому должно изменить ItemsPanel ListView. Панелью по умолчанию является VirtualizingStackPanel, который только создает ListBoxItem в первый раз, когда они становятся видимыми. Если у Вас нет слишком многих объектов в Вашем списке, это не должна быть проблема.

<ListView>
   ...
   <ListView.ItemsPanel>
      <ItemsPanelTemplate>
         <StackPanel/>
      </ItemsPanelTemplate>
   </ListView.ItemsPanel>
</ListView>
3
ответ дан 29 November 2019 в 03:44
поделиться

Спасибо за ту последнюю подсказку Sam. У меня было диалоговое окно, которое открылось, означая, что моя сетка потеряла фокус каждый раз закрытое диалоговое окно. Я использую это:

if(currentRow >= 0 && currentRow < lstGrid.Items.Count) {
    lstGrid.SelectedIndex = currentRow;
    lstGrid.ScrollIntoView(lstGrid.SelectedItem);
    if(shouldFocusGrid) {
        ListViewItem item = lstGrid.ItemContainerGenerator.ContainerFromItem(lstGrid.SelectedItem) as ListViewItem;
        item.Focus();
    }
} else if(shouldFocusGrid) {
    lstGrid.Focus();
}
2
ответ дан 29 November 2019 в 03:44
поделиться

Я внес некоторые изменения в Sams ответ. Обратите внимание, что я хотел перейти к последней строке. К сожалению, ListView иногда просто отображал последнюю строку (даже если над ней было, например, 100 строк), поэтому я исправил это следующим образом:

    public void ScrollToLastItem()
    {
        if (_mainViewModel.DisplayedList.Count > 0)
        {
            var listView = myListView;
            listView.SelectedItem = listView.Items.GetItemAt(_mainViewModel.DisplayedList.Count - 1);
            listView.ScrollIntoView(listView.Items[0]);
            listView.ScrollIntoView(listView.SelectedItem);
            //item.Focus();
        }
    }

Cheers

5
ответ дан 29 November 2019 в 03:44
поделиться

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

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ScrollViewer scrollViewer = GetScrollViewer(lstVw) as ScrollViewer;
            scrollViewer.ScrollToHorizontalOffset(dataRowToFocus.RowIndex);
            if (dataRowToFocus.RowIndex < 2)
                lstVw.ScrollIntoView((Entity)lstVw.Items[0]);
            else
                lstVw.ScrollIntoView(e.AddedItems[0]);
        } 

 public static DependencyObject GetScrollViewer(DependencyObject o)
        {
            if (o is ScrollViewer)
            { return o; }

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
            {
                var child = VisualTreeHelper.GetChild(o, i);

                var result = GetScrollViewer(child);
                if (result == null)
                {
                    continue;
                }
                else
                {
                    return result;
                }
            }
            return null;
        } 

private void Focus()
{
 lstVw.SelectedIndex = dataRowToFocus.RowIndex;
 lstVw.SelectedItem = (Entity)dataRowToFocus.Row;

 ListViewItem lvi = (ListViewItem)lstVw.ItemContainerGenerator.ContainerFromItem(lstVw.SelectedItem);
ContentPresenter contentPresenter = FindVisualChild<ContentPresenter>(lvi);
contentPresenter.Focus();
contentPresenter.BringIntoView();

}
2
ответ дан 29 November 2019 в 03:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: