oronsultan Ответов: 0

Загрузите тяжелое пользовательское управление с помощью анимации laoding без замораживания приложения


Hi friends, so after more than a week of trying to solve it on my own I officially give up and turn to your help. Basically, it should not be so complicated so I have no idea why it does not work. I have a WPF app which contains a Main Window called surprise surpise...: Main_Window.
That window contain a user control called 'pageTransitionControl' that change its content according to what the client want to see. the 'pageTransitionControl' is there to support multiple animations and so on... Anyway, among all of the user controls,  i have a preety havy uc called ucBanks. before it shows, the ucBanks load a lot of data, manipulating it and display it on a very beautiful and smart charts. the problem is it takes some time to load it, approximately 6-7 seconds so i need the UI to show 'Loading' animation during that time (another user control called 'ucSpinner').
I'm Trying to load the ucBanks on a different thread to avoid freezing the application and it works great: the ucSpinner is showed immidiatlly and the ucBanks is loading on the background but when i change the content of the 'pageTransitionControl' i get this error:
"The calling thread cannot access this object because a different thread owns it".
I think i tried basically everything but i must missing somthing or doing somthing wrong.
This is where it all start, the btn_click event that load ucBanks:

ShowSpinner();
Thread.Sleep(100);
Thread newThread = new Thread(new ThreadStart(LoadUc));
newThread.SetApartmentState(ApartmentState.STA);
newThread.IsBackground = true;
newThread.Start();

This is the ShowSpinner method:

<pre lang="c#">private void ShowSpinner()
{
   ucSpinner.Opacity = 1;
}


и это метод LoadUc:

private void LoadUc()
{
     ucOsh ucOshx = new ucOsh();
     Utils.LoadUc(ucOshx, null, PageTransitions.PageTransitionType.GrowAndFade, true, this, null, true);
}


С LoadUc я позвонил статический класс, называемый 'утилиты' держа 'LoadUc' способ:

public static void LoadUc(System.Windows.Controls.UserControl ucParent, System.Windows.Controls.UserControl ucChild, PageTransitions.PageTransitionType tranType, bool removeChildrens = true, System.Windows.Window w = null, List<Plist.Plist> lst = null, bool hideMenu = false)
        {
            MainWindow win = null;
            if (w != null) { win = (MainWindow)w; }
            else { win = (MainWindow)System.Windows.Window.GetWindow(ucChild); }
            win.Dispatcher.Invoke(
            System.Windows.Threading.DispatcherPriority.ContextIdle, (System.Action)delegate
            {
                win.pageTransitionControl.TransitionType = tranType;
                win.pageTransitionControl.PARAMS = lst;
                win.pageTransitionControl.Tag = ucParent.ToString();
                win.pageTransitionControl.pages.Push(ucParent);
                win.pageTransitionControl.Content = ucParent;  ----------->>>>This is where i get the error!!!
            });
        }


Я понимаю, что главное окно заблокировано внутри другого потока, но я не вижу никакой другой возможности загрузить его, не замораживая все приложение.
Есть ли у кого-нибудь решение моей проблемы? СА : -)?

Что я уже пробовал:

я попробовал работать с background-worker, проверил все настройки диспетчера, загрузил пользовательский элемент управления внутри и снаружи потоков...

0 Ответов