我在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;
}
}
然后我在WPF应用程序中使用此UserControl,页面的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的背景改为AliceBlue以外的颜色并点击返回时会发生什么。
当我运行代码时,会看到正确的颜色,问题在于设计时通过XAML刷新。
非常感谢任何帮助我理解这里发生了什么的指示!
答案 0 :(得分:9)
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的绑定和动画系统)的人都会在属性更改后立即收到更新通知。
答案 1 :(得分: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)的前半部分,阅读起来很愉快,一切都会让更多更有意义。