Обновить WPF-Control по коду - PullRequest
3 голосов
/ 27 июля 2011

Я пытаюсь отключить кнопку для отказа в спаме. Нажмите на эту кнопку.

Я использовал делегат Refresh, чтобы Render вызывал элемент управления, но он отображается как включенный. Метод connect () - метод занимает около 4 секунд, когда кнопка отображается как активированная.

Где проблема?

public static class ExtensionMethods
{

   private static Action EmptyDelegate = delegate() { };


   public static void Refresh(this UIElement uiElement)
   {
      uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
   }
}


private void buttonConnect_Click(object sender, RoutedEventArgs e)
{
    this.Cursor = Cursors.Wait;
    buttonConnect.IsEnabled = false;
    buttonConnect.Refresh();

    if (buttonConnect.Content.Equals("Connect"))
    {
        connect();
    }
    else
    {
        disconnect();
    }
    buttonConnect.IsEnabled = true;
    buttonConnect.Refresh();
    this.Cursor = Cursors.Arrow;
}

Ответы [ 3 ]

4 голосов
/ 27 июля 2011

Поскольку все, что, по-видимому, происходит в потоке пользовательского интерфейса, у пользовательского интерфейса нет времени для обновления между ними, вам необходимо запустить задачу в фоновом потоке и снова изменить пользовательский интерфейс по завершении (например, использовать BackgroundWorker, который уже имеет событие RunWorkerCompleted).

например

button.IsEnabled = false;
var bw = new BackgroundWorker();
bw.DoWork += (s, _) =>
{
    //Long-running things.
};
bw.RunWorkerCompleted += (s,_) => button.IsEnabled = true;
bw.RunWorkerAsync();
1 голос
/ 27 июля 2011

еще лучше, вместо того, чтобы возиться с событиями, почему бы не использовать привязку ICommand, и там вы можете реализовать CanExecute, который может возвращать true / false в зависимости от того, хотите ли вы включить / отключить кнопку

Отличный пример здесь на ICommand

0 голосов
/ 27 июля 2011

Вы устанавливаете приоритет метода на Render, который на самом деле не выполняет никакого рендеринга.

Я бы сказал, что использование асинхронного вызова было бы наилучшим действием, позволяющим обработчику макетарендер:

private void buttonConnect_Click(object sender, RoutedEventArgs e)
{
    this.Cursor = Cursors.Wait; 
    buttonConnect.IsEnabled = false; 

    Action action = buttonConnect.Content.Equals("Connect") ? connect : disconnect;

    new Action(() => {
        action();
        Dispatcher.Invoke(() =>
            {
                buttonConnect.IsEnabled = true;
                this.Cursor = Cursors.Arrow;
            });
    }).BeginInvoke(null, null);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...