|
ContainerFromItem
|
|||
---|---|---|---|
#18+
Исходная задача: Есть набор данных класса CItem подключенных через ListCollectionView к DataGrid: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
Зная конкретный элемент этого набора я пытаюсь получить объект строки этого грида: Код: c# 1. 2. 3. 4. 5.
Первая операция (dob1) работает Вторая операция (dob2) не хочет работать Почему безобидная операция освежения вьюхи приводит к такому результату? (Тестовый проектик приложен) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2019, 12:38 |
|
ContainerFromItem
|
|||
---|---|---|---|
#18+
скорее всего дело в виртуализации Grid1.ItemContainerGenerator.ContainerFromItem(item); возвращает элемент контейнера, который в момент обновления не существует. Refresh() вьюхи вызывает событие изменения с аргументом NotifyCollectionChangedAction.Reset и все элементы списка представления удаляются и заполняются по новой, по сути происходит пересоздание всех списка к исходной коллекции, вообще само обновление может содержать в себе другие элементы, я часто оборачиваю элементы представления, то есть представление возвращает не оригинальные объекты модели, а обёртку над ними, которую сама создает или элементы другого типа (типа NewItemPlaceholder'ы) и те, которые возможно я как разработчик хочет добавить. static public ObservableCollection<CItem> Items = new ObservableCollection<CItem>(); static public ListCollectionView View = new ListCollectionView(Items); делать такие поля статическими плохая практика, хоть компилятор и может разобраться, что Items нужно инициализировать до, а не после View. Лучше вообще такие объекты с событиями не использовать в статике. Вашего сценария лучше избегать, на самом деле, не надо пытаться из ViewModel или ICollectionView взаимодействовать с представлением, получать ссылки на объекты управления. DataGrid должен быть просто отражением состояния вашего представления, а в случае если вы используйте ICollectionView даже на уровне представления коллекции. А вот DataGrid может управлять представлением по средствам интерфейсов. Что он и делает когда вы управляется фильтрацией и сортировкой, группировкой и так далее, на сколько я помню для DataTable DataGrid использует не ListCollectionView, а если вы создадите свое представление коллекции, то будет использовать вашу, ну или которые вы задаете в сорс. Либо попробуйте отключить виртуализацию, но опять же так делать не стоит даже потому, что виртуализация может быть Recycled и вы получите вообще элемент другого объекта и т.д. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2019, 13:12 |
|
ContainerFromItem
|
|||
---|---|---|---|
#18+
ну и забыл сказать, что пересоздание всех этих элементов произойдет через Dispatcher с каким то приоритетом Loaded (на счет приоритета не уверен, но у виртуализируемых объектов при создание срабатывает событие Loaded). Как вариант после View.Refresh() попробуйте вызвать await Dispatcher.Yield(); не факт, что поможет, я не пробовал ваш код, мне лень и это вообще не безопасно, какие то файлы качать ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2019, 13:16 |
|
ContainerFromItem
|
|||
---|---|---|---|
#18+
граммарнаци )Извини, Роман, наболело Посредством , кого – чего – это производный предлог, который используется при управлении родительным падежом. Предлог – служебная часть речи, служит для выражения связи между словами. К предлогу нельзя поставить никакой вопрос. Образован от существительного “посредство” со значением “посредничество“. Посредник, посредничать, посредничество – это однокоренные слова, в конечном счете отнесенные к лицу, стоящему “посередине” – между двумя сторонами – и призывающее их к миру, согласию или взаимной выгоде при совершении сделки. Есть в русском языке и сочетание « по средствам » – предлог с существительным в дательном падеже, имеет значение: согласно достатку . Если допустить ошибку в окончании, получится сходство с предлогом по звучанию. Отличить это сочетание от предлога “посредством” достаточно легко: в сочетании предлога и существительного между ними можно вставить другое слово, например, “По моим, скромным средствам”. Подробнее: https://obrazovaka.ru/kak-pishetsya/posredstvom.html#ixzz641I7xOcz ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2019, 13:20 |
|
ContainerFromItem
|
|||
---|---|---|---|
#18+
Спасибо Роман за развернутый ответ. Приложенный проектик можно и не открывать. Я его создал для того, чтобы, при желании, можно было посмотреть на полную схему создаваемых данных и списков. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2019, 17:57 |
|
ContainerFromItem
|
|||
---|---|---|---|
#18+
Roman Mejtesну и забыл сказать, что пересоздание всех этих элементов произойдет через Dispatcher с каким то приоритетом Loaded (на счет приоритета не уверен, но у виртуализируемых объектов при создание срабатывает событие Loaded). Как вариант после View.Refresh() попробуйте вызвать await Dispatcher.Yield(); не факт, что поможет, я не пробовал ваш код, мне лень и это вообще не безопасно, какие то файлы качать Поможет-поможет. Непосредственно после ICollectionView.Refresh никаких контейнеров еще не существует, их создание в очереди диспетчера. Вот это: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
выводит False и False - приоритет ContextIdle ставит операцию после всего, что может влиять на компоновку визуального дерева. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2019, 22:02 |
|
|
start [/forum/topic.php?fid=21&msg=39884229&tid=1440306]: |
0ms |
get settings: |
11ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
34ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
41ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 132ms |
0 / 0 |