В вашем коде я вижу две ключевые проблемы:
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;
}
Я думаю, что проблема здесь состоит в том, что 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);
Кто-то сказал мне еще лучший способ прокрутить к определенной строке, которая легка и работает как очарование.
Короче говоря:
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 :
Одно обходное решение к этому должно изменить ItemsPanel ListView. Панелью по умолчанию является VirtualizingStackPanel, который только создает ListBoxItem в первый раз, когда они становятся видимыми. Если у Вас нет слишком многих объектов в Вашем списке, это не должна быть проблема.
<ListView>
...
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Спасибо за ту последнюю подсказку 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();
}
Я внес некоторые изменения в 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
Попробуйте это
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();
}