Как показать анимацию при создании пользовательского элемента управления - PullRequest
4 голосов
/ 26 января 2011

В приложении WPF 4 у меня очень большой пользовательский элемент управления, полный элементов управления, для инициализации которого на быстром компьютере требуется что-то вроде 4s.В течение этого времени приложение, конечно, вообще не отвечает.
Есть ли способ показать анимацию в главном окне, пока этот элемент управления инициализирован?

Я понимаю, что не могу создать его в другом потоке.Но есть ли способ создать его с более низким приоритетом из диспетчера, чтобы я мог показать вращающееся колесо или около того в главном окне, которое все еще вращалось бы?

(Единственное решение, которое я могу придумать правильноТеперь можно разбить пользовательский элемент управления на дополнительные части и загружать их только при необходимости. Но для изменения потребуется много времени разработки.)

Update1
Чтобы быть болееясно: это простое окно WPF с использованием вкладок.Когда открывается новая вкладка, я инициализирую пользовательский элемент управления, который содержит элементы управления для этой вкладки.Один из этих пользовательских элементов управления настолько полон элементов управления, что для отображения новой вкладки требуется 4 секунды.
Поэтому я подумал, что показ вращающегося колеса будет лучше, чем заблокированное приложение.

Ответы [ 3 ]

5 голосов
/ 26 января 2011

Я думаю, вам придется разбить этот пользовательский элемент управления на части. Что вы можете сделать, это использовать BackgroundWorker для координации «создания» этого пользовательского элемента управления. Каждый раз, когда происходит событие DoWork, используйте Dispatcher.BeginInvoke для создания добавления следующего элемента управления в пользовательский интерфейс. Эта техника описана в следующем сообщении в блоге:

http://loekvandenouweland.com/index.php/2010/12/wp7-add-user-controls-graphics-in-background-thread/

Это позволит вам показать анимацию во время загрузки.

2 голосов
/ 26 января 2011

Почему вы не можете инициализировать его в другом потоке?Я вижу два сценария:

  1. Инициализация медленная по причинам, не связанным с WPF, которые предварительно загружаются / предварительно вычисляются в другом потоке перед входом в базовую инициализацию WPF.
  2. Сам WPF потребляет 4 секундыПроцессорное время (хотя, это действительно WTF-уровни процессорного времени ...).Если это так, вы можете запустить другой поток STA с собственным насосом сообщений, который может отображать независимый пользовательский интерфейс (например, вращающееся колесо) до тех пор, пока не завершится загрузка основного потока.

Вы можете создавать «диалоги»которые неявно создают новый Dispatcher и запускаются в фоновом потоке, или вы можете явно создать свой собственный Dispatcher (= насос сообщений).

Для этого я использую следующий метод:

public static Dispatcher StartNewDispatcher(ThreadPriority cpuPriority = ThreadPriority.Normal) {
    using (var sem = new SemaphoreSlim(0)) {
        Dispatcher retval = null;
        var winThread = new Thread(() => {
            retval = Dispatcher.CurrentDispatcher;
            sem.Release();
            Dispatcher.Run();
        }) { IsBackground = true, Priority = cpuPriority };
        winThread.SetApartmentState(ApartmentState.STA);
        winThread.Start();
        sem.Wait();
        return retval;
    }
}

Это дает вам настоящий многопоточный интерфейс;но это также означает, что вы не можете связать данные или каким-либо другим способом напрямую обмениваться данными между двумя пользовательскими интерфейсами: в конце концов, объекты WPF имеют привязку к потокам.

Прежде чем идти по этому пути, убедитесь, что нет никаких медленныхкомпоненты, которые можно предварительно загрузить с помощью профилировщика: вариант 1 (предварительная загрузка тяжелых материалов перед инициализацией WPF) проще и понятнее.

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

Решением может быть перемещение медленной части (загрузка данных? Которая не принадлежит IN элемента управления) в другой поток, как вы упомянули.

Или используйте VirtualizingStackPanel для отложенной загрузки необходимого.

Не могли бы вы уточнить причину задержки?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...