我是 WPF 的新手,所以我对如何做到这一点有点不知所措。我今天创建了一个非常简单的视觉UserControl
,它由一个网格组成,显示一个圆圈,两条虚线穿过它。目的是显示给定半径尺寸的圆。我喜欢能够隐藏高度和宽度,并使用名为RadiusSize
的自定义属性来设置控件的大小。
Code Behind定义RadiusSize
依赖属性,如下:
public static readonly DependencyProperty RadiusSizeProperty =
DependencyProperty.Register("RadiusSize", typeof(double), typeof(Radius));
public double RadiusSize
{
get { return (double)GetValue(RadiusSizeProperty); }
set
{
SetValue(RadiusSizeProperty, value);
Height = value * 2;
Width = value * 2;
RaisePropertyChanged("RadiusSize");
}
}
在为给定的Radius
控件设置XAML并且遗憾地将RadiusSize
传递给Auto
时,高度或宽度属性没有明显变化。如果删除,则默认为{{1}}。我想做什么?
答案 0 :(得分:2)
问题是您已将逻辑放入DependencyProperty周围的'clr包装器属性'的setter中。这在WPF中不起作用。您应该将代码放入DependencyProperty声明中的DependencyPropertyChangedCallback。看看This tutorial
除此之外,您可以使用椭圆在屏幕上绘制圆圈,而不必实现自己的圆圈。
您的RaisePropertyChanged方法有何功能?您不应该在基于DependencyObject的类中实现INotifyPropertyChanged。
答案 1 :(得分:2)
是的,有可能。不,你做得不对。
有点难以判断你是如何在圆上设置宽度/高度的,但是你的代码中明显的新手错误就是你在DependencyProperty的setter中做了一些事情。
DP Binding
未通过您的媒体资源的getter / setter访问。绑定系统在幕后工作,因此如果您绑定到类上的DP,则getter /更新绑定时不会调用setter。
那么,有哪些替代方案?许多。您可以将PropertyMetadata实例添加到指定回调的属性声明中,并在该回调中更新其他属性...或者您可以完全避免它。我会选择第二个。
如果我打算创建一个带有椭圆和其他图形的UserControl,我只需在ViewBox中拍摄视觉效果并自动拉伸到UserControl的大小,并忘记整个半径的东西。
但是如果您仍然对半径感兴趣,可以使用IValueConverter来完成工作。
public class RadiusConverter : IValueConverter
{
public object Convert(object value, /*snip*/)
{
// check null, type, and double.NaN here
return (double)value * 2;
}
/* snip, on the round trip same as before but / 2 */
}
然后,在您的UserControl中定义Radius
属性,并
<UserControl x:Class="Derp"
Width="{Binding Radius, Converter={StaticResource RadiusConverter}, RelativeSource={RelativeSource Self} />
<!-- snip -->
答案 2 :(得分:0)
看起来很好,只是,当您设置控件的高度时,您可能没有修改内部圆的高度,请尝试设置圆的高度和您包含的网格。
答案 3 :(得分:0)
正如另一张海报指出的那样,您将无法使用属性系统设置高度和宽度。相反,如果您想要自动设置控件的高度和宽度,则需要为RadiusSizeProperty
DependencyProperty定义回调。
当你设置RadiusSize:
时,这样的东西会为你设置高度和宽度 Public Shared RadiusSizeProperty As DependencyProperty = DependencyProperty.Register("RadiusSize",
GetType(Double),
GetType(Radius),
New PropertyMetadata(0.5, Sub(s, e)
Dim p As DependencyPropertyChangedEventArgs = e
Dim o As DependencyObject = s
o.SetValue(HeightProperty, p.NewValue)
o.SetValue(WidthProperty, p.NewValue)
End Sub))