WPF ожидающее сообщение при рендеринге шаблона - PullRequest
0 голосов
/ 04 февраля 2020

В моем старом проекте у меня есть древовидная структура и событие OnClick, связанное с листьями древовидной структуры. По сути, каждый раз, когда я выбираю лист, я получаю тип узла и применяю шаблон в элементе управления, например:

gridDati.Template = Resources["tmplBit"] as ControlTemplate;

"tmplBit" - это DataTemplate с несколькими столбцами. Все работает нормально, но иногда, когда у меня 20 столбцов и 30/40 записей, это требует времени (4/5 se c) при применении выбранного шаблона. Я хотел бы показать ожидающее сообщение или что-то в этом роде, но не могу найти, как. У меня уже есть окно, которое показывает ожидающее сообщение, я пытался использовать как:

    var aboutBox = new winWaitingMessage(Global.LM.T("@_3261_Inizio export"));
    aboutBox.Show();

    // Template?
    gridDati.Template = Resources["tmplBit"] as ControlTemplate;

    aboutBox.Close();

, но окно закрывается сразу, поэтому я не могу найти событие, которое сообщит мне, когда шаблон применяется и отображается , Есть намеки?

Ответы [ 2 ]

0 голосов
/ 05 февраля 2020

Вы можете использовать задачу

[DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr FindWindow(IntPtr hwnd, string title);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int PostMessage(IntPtr hwnd, int msg, uint wParam, uint lParam);
        public const int WM_CLOSE = 0x10; 

        public const int WM_KEYDOWN = 0x0100;

        public const int WM_KEYUP = 0x0101;

        public const int VK_RETURN = 0x0D;


        private   void Button_Click(object sender, RoutedEventArgs e)
        {
            Task task1 = new Task(() => 
            {

                   gridDati.Template = Resources["tmplBit"] as ControlTemplate;

            });
            task1.Start();
            Task cwt = task1.ContinueWith(t=>
            {
                FindAndKillWindow("Warning");
            });
            MessageBox.Show("Waiting...", "Warning");        
        }

        private static void FindAndKillWindow(string title)
        {
            IntPtr ptr = FindWindow(IntPtr.Zero, title);
            if (ptr != IntPtr.Zero)
            {
                int ret = PostMessage(ptr, WM_CLOSE, 0, 0);

                ptr = FindWindow(IntPtr.Zero, title);
                if (ptr != IntPtr.Zero)
                {
                    PostMessage(ptr, WM_KEYDOWN, VK_RETURN, 0);
                    PostMessage(ptr, WM_KEYUP, VK_RETURN, 0);
                }
            }
        }
0 голосов
/ 04 февраля 2020

Каркас не предоставляет такого события, но вы можете обработать событие Loaded для элемента в шаблоне и закрыть окно при возникновении этого события, например:

gridDati.Template = Resources["tmplBit"] as ControlTemplate;
gridDati.ApplyTemplate();
FrameworkElement fe = gridDati.Template.FindName("YourElement", gridDati) as FrameworkElement;
if (fe == null)
{
    aboutBox.Close();  
}
else
{
    void Fe_Loaded(object sender, RoutedEventArgs e)
    {
        aboutBox.Close();
        fe.Loaded -= Fe_Loaded;
    }
    fe.Loaded += Fe_Loaded;
}

XAML:

<ControlTemplate x:Key="tmplBit">
    ...
    <Button x:Name="YourElement" ... />

Редактировать: Если вы не хотите или не можете использовать локальную функцию по какой-либо причине, вы можете использовать лямбда-выражение для достижения того же:

...
else
{
    RoutedEventHandler loadedHandler = null;
    loadedHandler = (s, e) =>
    {
        aboutBox.Close();
        fe.Loaded -= loadedHandler;
    };
    fe.Loaded += loadedHandler;
}
...