Обновить WPF UserControl через XAML - PullRequest
1 голос
/ 27 мая 2009

Я использую WPF в Visual Studio 2008. У меня есть простой WPF UserControl со следующим кодом:

  public partial class UserControl1 : UserControl
  {
    public UserControl1()
    {
      InitializeComponent();
      Composite = new Composite();
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
      //LayoutRoot is name of default Grid instance
      if (!LayoutRoot.Children.Contains(Composite))
      {
        LayoutRoot.Children.Add(Composite);
      }
    }

    public Composite Composite
    {
      get;
      set;
    }
  }

  public class Composite : ContentControl
  {
    protected override void OnRender(DrawingContext drawingContext)
    {
      drawingContext.DrawRectangle(new SolidColorBrush(Color), new Pen(Brushes.Black, 1.0), new Rect(RenderSize));
    }

    public Color Color
    {
      get;
      set;
    }
  }

Затем я использую этот UserControl в приложении WPF, XAML страницы выглядит следующим образом:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:test="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"
    Title="Window1" Height="500" Width="700" Background="AliceBlue">
  <test:UserControl1 Name="uControl1">
    <test:UserControl1.Composite>
      <test:Composite Color="Green"/>
    </test:UserControl1.Composite>
  </test:UserControl1>
</Window>

Мой вопрос: какой код я должен добавить к вышеперечисленному, чтобы, изменив «Composite Color» на что-то отличное от зеленого и нажав кнопку возврата, UserControl автоматически обновился? Я ищу то поведение, которое происходит, когда вы меняете фон окна Window1 на цвет, отличный от AliceBlue, и нажимаете return.

Когда я запускаю код, отображается правильный цвет, проблема заключается в обновлении во время разработки через XAML.

Большое спасибо за любые указатели, которые помогают мне понять, что здесь происходит!

Ответы [ 2 ]

9 голосов
/ 27 мая 2009

WPF оптимизирован для повторного рисования элементов, когда это абсолютно необходимо, поэтому поведение, которое вы видите, отчасти потому, что WPF не знает, что при изменении Composite.Color ему необходимо заново нарисовать элемент управления.

Кроме того, дизайнер Visual Studio / Blend (или элементы управления XAML) не сможет заметить, что это свойство изменилось, поскольку ваш элемент управления не сигнализирует об изменении этого свойства; без этого уведомления WPF не знает, что свойство изменено (что избавляет его от необходимости постоянно проверять наличие изменений).

Хотя вы могли бы реализовать INotifyPropertyChanged и исправить вторую проблему, поскольку вы наследуете от ContentControl (который высоко в иерархии наследования реализует INotifyPropertyChanged), вы можете использовать DependencyProperty и исправить обе проблемы - и получить лучшее связывание WPF поддержка, чтобы загрузить!

// DependencyProperty backing store for Color.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ColorProperty =
    DependencyProperty.Register("Color", typeof(Color), typeof(Composite), 
    new FrameworkPropertyMetadata(new Color(), FrameworkPropertyMetadataOptions.AffectsRender));

public Color Color
{
    get { return (Color)GetValue(ColorProperty); }
    set { SetValue(ColorProperty, value); }
}

Устанавливая FrameworkPropertyMetadataOptions.AffectsRender , WPF знает, что при изменении этого свойства необходимо повторно выполнить проход рендеринга для этого элемента, и повторно выполнит рендеринг вашего элемента управления, вызвав метод OnRender (). и отображение нового цвета. И, как DependencyProperty, он автоматически генерирует правильное событие PropertyChanged, так что любой, кто наблюдает за вашим классом (например, системой связывания и анимации WPF), получит уведомление об обновлении, как только свойство будет изменено.

0 голосов
/ 28 мая 2009

Вы делаете это очень странным образом (напоминает управление MFC); Потратьте некоторое время и прочитайте первую половину WPF Unleashed или около того (http://www.amazon.com/Windows-Presentation-Foundation-Unleashed-WPF/dp/0672328917/ref=sr_1_1?ie=UTF8&s=books&qid=1243491021&sr=8-1), читать приятно, и все будет иметь много больше смысла.

...