1

Visual Studio 2008 内で WPF を使用しています。次のコードを含む単純な 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>

私の質問は次のとおりです。「複合色」を緑以外に変更して戻るボタンを押すと、UserControl が自動的に更新されるように、上記にどのコードを追加する必要がありますか? 私が探している動作は、Window1 の Background を AliceBlue 以外の色に変更して Return キーを押したときに起こることです。

コードを実行すると正しい色が表示されますが、問題は XAML を介したデザイン時の更新にあります。

ここで何が起こっているのかを理解するのに役立つポインタに感謝します!

4

2 に答える 2

9

WPFは、どうしても必要な場合にのみアイテムを再描画するように最適化されているため、表示される動作は、Composite.Colorを変更したときに、コントロールを再描画する必要があることをWPFが認識していないためです。

さらに、Visual Studio / Blendデザイナー(またはXAMLコントロール)は、コントロールがそのプロパティが変更されたことを通知しないため、そのプロパティが変更されたことに気付くことはありません。その通知がない場合、WPFはプロパティが変更されたことを認識しません(これにより、変更があったかどうかを常に確認する必要がなくなります)。

INotifyPropertyChangedを実装して2番目の問題を修正することはできますが、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のバインディングやアニメーションシステムなど)に更新が通知されます。

于 2009-05-27T16:57:35.613 に答える
0

あなたはこれを非常に奇妙な方法で行っています(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)、読むのは楽しいですし、すべてがはるかに理にかなっています。

于 2009-05-28T06:11:52.353 に答える