代码之家  ›  专栏  ›  技术社区  ›  serhio

自定义从属属性问题

  •  0
  • serhio  · 技术社区  · 15 年前

    任务:

    有一个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>
    

    所以,测试画布中的线不跟随圆的中心。。。为什么?

    编辑:


    在代码或设计器中,我 这个 CenterX公司 中心点Y坐标

    2 回复  |  直到 15 年前
        1
  •  1
  •   Kris    15 年前

    您从未实际设置过CenterX和CenterY,因此它们将保持默认值,但还有其他问题。这个问题似乎是家庭作业,所以我就指出问题所在。

    Coerce handlers

    你需要额外的物业吗?如果你设置左上方,他们需要更新吗?如果是的话 custom Attached Properties

        2
  •  0
  •   Mediator    15 年前

    你需要这样的结果吗?

    exmpale

    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>
    

    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;
        }
    }
    

    装订是工作…还是你需要别的东西?