我在WPF userControls上对自定义依赖项属性进行了测试,但是没有用...请帮忙。
拥有UserControl - MyCircle,构建CenterX
和CenterY
可绑定属性。
这是我的代码:
MyTestCircle.xaml
<Canvas x:Name="mainCanvas" Width="100" Height="100">
<Ellipse x:Name="myCircle" Fill="Red"
Width="{Binding ElementName=mainCanvas, Path=ActualWidth}"
Height="{Binding ElementName=mainCanvas, Path=ActualHeight}"/>
</Canvas>
MyTestCircle.xaml.cs
public partial class MyTestCircle : UserControl
{
public MyTestCircle()
{
InitializeComponent();
}
public double CenterX
{
get { return (double)GetValue(CenterXProperty); }
set { SetValue(CenterXProperty, value); }
}
public static readonly DependencyProperty CenterXProperty =
DependencyProperty.Register("CenterX", typeof(double), typeof(MyTestCircle),
new UIPropertyMetadata(double.NaN,
new PropertyChangedCallback(OnCenterYChanged),
new CoerceValueCallback(OnCenterXCoerceValue)));
public static void OnCenterXChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
MyTestCircle circle = (MyTestCircle)obj;
Canvas.SetLeft(circle, (double)args.NewValue - circle.Width / 2);
}
public static object OnCenterXCoerceValue(DependencyObject source, object obj)
{
MyTestCircle circle = (MyTestCircle)obj;
return Canvas.GetLeft(circle) + circle.Width / 2;
}
public double CenterY
{
get { return (double)GetValue(CenterYProperty); }
set { SetValue(CenterYProperty, value); }
}
public static readonly DependencyProperty CenterYProperty =
DependencyProperty.Register("CenterY", typeof(double), typeof(MyTestCircle),
new UIPropertyMetadata(double.NaN,
new PropertyChangedCallback(OnCenterYChanged),
new CoerceValueCallback(OnCenterYCoerceValue)));
public static void OnCenterYChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
MyTestCircle circle = (MyTestCircle)obj;
Canvas.SetTop(circle, (double)args.NewValue - circle.Height / 2);
}
public static object OnCenterYCoerceValue(DependencyObject source, object obj)
{
MyTestCircle circle = (MyTestCircle)obj;
return Canvas.GetTop(circle) + circle.Height / 2;
}
}
测试画布:
<Canvas x:Name="mainCanvas">
<my:MyTestCircle Canvas.Left="104" Canvas.Top="132" x:Name="myTestCircle1" />
<Line Stroke="Black"
X1="0" Y1="0"
X2="{Binding ElementName=myTestCircle1, Path=CenterX}"
Y2="{Binding ElementName=myTestCircle1, Path=CenterY}"
/>
</Canvas>
因此,测试画布中的Line不会跟随圆圈的中心...为什么?
注:
在代码或设计器中,我永远不会隐藏 CenterX
和CenterY
属性。我需要将这些属性与Left / Top画布属性“链接”......这可能吗?
答案 0 :(得分:1)
您实际上从未设置过CenterX和CenterY,因此它们保持默认状态,但还有其他问题。问题似乎是homeworkey所以我只是指出问题。
如果您想在设置值之前调整值,则使用Coerce handlers,例如限制价值。在这种情况下,他们不需要加上你错误地施放obj,这是MyTestCircle的双倍。
您的更改处理程序正在使用尚未设置的MyTestCircle UserControl的宽度和高度,您应该设置它们或访问已设置的大小值。您可以在用户控件中使用Ellipse并设置UserControl的大小。当X发生变化时,你也会有一个错字调用Y处理程序。
如果这是家庭作业,试着解决上面提到的问题,我们可以再看看。如果没有,你只想要一条线到中心我会删除属性完全使用内置的Left,Top属性并添加一个转换-50,-50的RenderTransform。
您需要额外的属性吗?如果设置Left和Top,他们是否需要更新?如果是这样custom Attached Properties将是一个很好的解决方案。
答案 1 :(得分:0)
你需要这样的结果吗?
public Circle()
{
InitializeComponent();
}
public double CenterX
{
get { return (double)GetValue(CenterXProperty); }
set { SetValue(CenterXProperty, value); }
}
public static readonly DependencyProperty CenterXProperty =
DependencyProperty.Register("CenterX", typeof(double), typeof(Circle),
new UIPropertyMetadata(double.NaN,
new PropertyChangedCallback(OnCenterXChanged),
new CoerceValueCallback(OnCenterXCoerceValue)));
public static void OnCenterXChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
Circle circle = (Circle)obj;
Canvas.SetLeft(circle, (double)args.NewValue - circle.Width / 2);
}
public static object OnCenterXCoerceValue(DependencyObject source, object obj)
{
return double.Parse(obj.ToString());
}
public double CenterY
{
get { return (double)GetValue(CenterYProperty); }
set { SetValue(CenterYProperty, value); }
}
public static readonly DependencyProperty CenterYProperty =
DependencyProperty.Register("CenterY", typeof(double), typeof(Circle),
new UIPropertyMetadata(double.NaN,
new PropertyChangedCallback(OnCenterYChanged),
new CoerceValueCallback(OnCenterYCoerceValue)));
public static void OnCenterYChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
Circle circle = (Circle)obj;
Canvas.SetTop(circle, (double)args.NewValue - circle.ActualHeight / 2);
}
public static object OnCenterYCoerceValue(DependencyObject source, object obj)
{
return double.Parse(obj.ToString());
}
<Canvas x:Name="mainCanvas" Width="100" Height="100">
<Ellipse x:Name="myCircle" Fill="Red"
Width="{Binding ElementName=mainCanvas, Path=Width}"
Height="{Binding ElementName=mainCanvas, Path=Height}"/>
</Canvas>
用于在MainWindows中测试创建^
private void Window_Loaded(object sender, RoutedEventArgs e)
{
myTestCircle1.CenterY = 200;
myTestCircle1.CenterX = 300;
}
编辑:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Left)
{
myTestCircle1.CenterX -= 1.0;
}
else if (e.Key == Key.Right)
{
myTestCircle1.CenterX += 1.0;
}
}
绑定是有效的......或者你还需要别的什么?