Как запретить редакторам закрываться, когда фоновая обработка обновляет узел XtraTreeList?

Я использую элемент управления DevExpress Xtra TreeList для отображения иерархического набора вопросов и ответов - подумайте о сложной форме опроса, содержащей разделы, подразделы и различные вопросы.

Форма работает в несвязанном режиме, без набора данных или привязки данных.

В качестве части информации, отображаемой для каждого вопроса, некоторый фон получается путем вызова веб-службы в фоновом потоке; результаты этих вызовов веб-службы затем используются для заполнения TreeList через вызовы TreeListNode.SetValue(),

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

Как я могу убедиться, что эти фоновые обновления не влияют на процесс редактирования пользователя?

Единственные похожие вопросы, которые я нашел, были на форумах DevExpress, где это предложение - принудительная фиксация записей пользователя, которая предотвращает потерю данных, но в остальном ничего не делает для исправления плохого взаимодействия с пользователем. Поскольку все они датируются 2007 годом, я надеюсь, что ситуация изменилась. Можно ли обновить узлы, не изменяя состояния собственной активности пользователей?

Предыстория: типичный экран будет иметь более 500 строк, при этом для вызова каждой веб-службы требуется около 0,6 с. Принудительное принятие или отмена действий пользователя каждые 0,6 с просто неприемлемо, и принуждение пользователей ждать завершения обработки (>5 минут), прежде чем они смогут внести какие-либо изменения, также плохо.

2 ответа

Решение

Краткий ответ: вы не можете

Изменение значения в TreeList приведет к отмене любого текущего пользовательского редактирования, независимо от того, используется Binding или нет.

Официальный ответ от DevExpress:

К сожалению, нет способа предотвратить закрытие активного редактора при изменении значений источника данных. Это невозможно сделать, потому что TreeList всегда должен быть синхронизирован с базовыми данными. Эта функциональность реализуется через интерфейс IBindingList обычным способом. В ответ на уведомление об изменении treeList должен обновить себя и, как следствие, перезагрузить данные. Это приводит к сбросу активного состояния редактирования.

Однако существует несколько разных способов введения требуемой функциональности. Например, вы можете создать отдельную форму, которая будет содержать набор редакторов, которые предоставят возможность редактировать определенный объект напрямую. Другой возможный способ достижения этой цели - создать промежуточное хранилище, которое будет кешировать все изменения. Синхронизация с источником данных TreeList должна выполняться по запросу пользователя.

Ну, один из способов, которым я смог это сделать - это ShowEditor() после небольшой задержки после события, которое выполняет обновление (скажем, 100 миллисекунд). Я получил бы проблему из-за notifypropertyaled обновления, и я бы зацепил FocusedNodeChanged. Например:

FocusedNodeChanged += OnNodeChanged;
private void OnNodeChanged(object s, FocusedNodeChangedEventArgs e)
    {
        _delayer.Start();
    }
private void _delayer_Tick(object sender, EventArgs e)
    {
        ShowEditor();
        _delayer.Stop();
    }

_delayer - класс Timer с тиковым событием. Немного грубо, но это делает свое дело.

Другие вопросы по тегам