Обновление текстового элемента управления WPF только в диспетчере - PullRequest
0 голосов
/ 30 апреля 2020

В моем приложении у меня есть линейный макет, который содержит динамически добавленные пользовательские элементы управления. Эти контроли обозначены как 1, 2, 3 et c. как они добавлены. У каждого элемента управления есть своя кнопка, чтобы удалить его из макета. Я пытаюсь обновить нумерацию при добавлении / удалении пользовательских элементов управления; однако метки в пользовательских элементах управления не обновляются. Следующий код - это то, что я использую для обновления меток:

private void UserControlThingHappened(object sender, EventArgs e)
    {
        DecreaseSmeCount();
        foreach (object child in smePanel.Children)
        {
            if (child is SMEInfoUserControl)
            {               
                Dispatcher.BeginInvoke(new System.Action(() =>
                {
                    (child as SMEInfoUserControl).SMENumber = "test";
                    MessageBox.Show((child as SMEInfoUserControl).SMENumber);
                }), DispatcherPriority.Normal);                 
                MessageBox.Show((child as SMEInfoUserControl).SMENumber);
            }
        } 
    }

Текстовое поле меток обновляется до «test» в диспетчере, но после диспетчера изменяется на свой исходный текст ( первое окно сообщения показывает тест, а второе показывает исходный текст). Спасибо за помощь!

1 Ответ

0 голосов
/ 01 мая 2020

Метод Dispatcher.BeginInvoke выполняет делегат асинхронно в потоке, с которым связан Dispatcher. так что в вашем коде вы получите два значения. один «тест», а другой - исходное значение SMENumber, поскольку окна сообщений отображаются асинхронно друг с другом, и нет никакой гарантии, какой из них («тест» или оригинал) будет отображаться первым.

сделайте ваш код рабочим, используя async и await. как показано ниже: (Этот код просто показывает, что SMENumber обновляется правильно).

private async void UserControlThingHappened(object sender, EventArgs e)
{
    DecreaseSmeCount();
    foreach (object child in smePanel.Children)
    {
        if (child is SMEInfoUserControl control)
        {   
            await Dispatcher.BeginInvoke(new System.Action(() =>
            {
                control.SMENumber = "test";
                MessageBox.Show(control.SMENumber);
            }), DispatcherPriority.Normal); 
            MessageBox.Show(control.SMENumber);
        }
    } 
}

В обоих окнах сообщений должен отображаться «тест».

Для обновления textBlocks убедитесь, что ваша привязка работает правильно и используйте этот код:

private void UserControlThingHappened(object sender, EventArgs e)
{
    DecreaseSmeCount();
    foreach (object child in smePanel.Children)
    {
        if (child is SMEInfoUserControl control)
        {   
            Dispatcher.BeginInvoke(new System.Action(() =>
            {
                control.SMENumber = "test";
            }), DispatcherPriority.Normal); 
        }
    } 
}

Если ваша привязка будет в порядке, то текстовые блоки должны быть обновлены.

Надеюсь, это поможет вам решить вашу проблему.

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