Почему мой рекламодатель не выполняет повторную визуализацию, когда элемент, к которому он применяется, изменяется?

Swiftmailer - еще один простой в использовании сценарий, который автоматически защищает от электронной почты и делает вложения легким. Я также настоятельно рекомендую использовать встроенную функцию mail() PHP.

Чтобы использовать:

  • Загрузите Swiftmailer и поместите lib в вашем проекте
  • Включите основной файл с помощью require_once 'lib/swift_required.php';

Теперь добавьте код, когда вам нужно отправить по электронной почте:

// Create the message
$message = Swift_Message::newInstance()
    ->setSubject('Your subject')
    ->setFrom(array('webmaster@mysite.com' => 'Web Master'))
    ->setTo(array('receiver@example.com'))
    ->setBody('Here is the message itself')
    ->attach(Swift_Attachment::fromPath('myPDF.pdf'));

//send the message          
$mailer->send($message);

Более подробную информацию и параметры можно найти в Документах Swiftmailer .

16
задан Robert Rossney 15 March 2010 в 21:28
поделиться

2 ответа

WPF имеет встроенный механизм, который заставляет все Adorners повторно измерять, переупорядочивать и повторно отображать каждый раз, когда соответствующий AdornedElement изменяет размер, положение или преобразование. Этот механизм требует от вас соблюдения определенных правил при написании кода для украшения, не все из которых задокументированы так четко, как следовало бы.

Сначала я отвечу на ваш заглавный вопрос о , почему ваш рекламный щит не постоянно перерисовывается, а затем объясню, как это исправить.

Почему украшение не отображается повторно

Каждый раз, когда AdornerLayer получает уведомление LayoutChanged, он сканирует каждый из своих украшений, чтобы увидеть, не изменился ли AdornedElement в размере, положении или преобразовании. Если это так, он устанавливает флаги, чтобы заставить Adorner снова измерить, упорядочить и отрендерить - примерно эквивалентно InvalidateMeasure (); InvaliateArrange (); InvalidateVisual (); .

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

Правильно реализованный Adorner или другой UIElement будет осторожно вызывать InvalidateVisual () каждый раз, когда это может повлиять на рендеринг , кроме ] Свойства зависимости AffectsRender были изменены.

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

В вашей ситуации, вероятно, происходит следующее:

  • Макет завершается, и запускается событие LayoutChanged .
  • AdornerLayer обнаруживает изменение размера на вашем AdornedElement
  • AdornerLayer планирует повторное измерение, изменение макета и повторную визуализацию вашего украшения.
  • Что-то вызывает вызов Arrange () , что приводит к повторному макету и повторному рендерингу до того, как повторно измерить. Это заставляет WPF думать, что украшение больше не нуждается в повторном макете или повторном рендеринге.
  • Механизм компоновки обнаруживает, что рекламный элемент нуждается в измерении, и вызывает Measure
  • Рекламный элемент MeasureOverride повторно вычисляет желаемый размер , но ничего не делает, чтобы сообщить WPF, что рекламный элемент необходимо повторно отобразить.
  • Механизм компоновки решает, что больше ничего не нужно делать, и поэтому украшение никогда не перерисовывает

Что вы можете сделать, чтобы это исправить

Решение, конечно же, состоит в том, чтобы исправить ошибку в Adorner , вызывая InvalidateVisual () каждый раз при повторном измерении элемента управления, например:

protected override Size MeasureOverride(Size constraint)
{
  var result = base.MeasureOverride(constraint);
  // ... add custom measure code here if desired ...
  InvalidateVisual();
  return result;
}

Выполнение этого заставит Adorner последовательно подчиняться всем правилам WPF, поэтому он будет работать как ожидается во всех ситуациях. Это также наиболее эффективное решение, поскольку InvalidateVisual () вообще ничего не будет делать, кроме тех случаев, когда это действительно необходимо.

58
ответ дан 30 November 2019 в 15:21
поделиться

Необходимо вызвать диспетчера на панели. Добавьте обработчик к событию TextBox SizeChanged:

    private void myTextBox_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        panel.Dispatcher.Invoke((Action)(() => 
        {
            if (panel.IsKeyboardFocusWithin)
            {
                // remove and add adorner to reset
                myAdornerLayer.Remove(myAdorner);
                myAdornerLayer.Add(myAdorner);
            }
        }), DispatcherPriority.Render, null);
    }

Это в основном происходит из этого поста: http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx

1
ответ дан 30 November 2019 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: