none
INotifyPropertyChanged change to DependencyObject RRS feed

  • 问题

  • Hi
    I have a class such as this:
    public class RtdField
    {
            #region SizeX

            public Double X1
            {
                get { return x1; }
                set
                {
                    x1 = value;
                    OnPropertyChanged("X1");
                    OnPropertyChanged("X");
                    OnPropertyChanged("OffsetX");
                }
            }
            private Double x1;


            public Double X2
            {
                get { return x2; }
                set
                {
                    x2 = value;
                    OnPropertyChanged("X2");
                    OnPropertyChanged("X");
                    OnPropertyChanged("OffsetX");
                }
            }
            private Double x2;


            public double X
            {
                get { return x1 + x2; }
                set
                {
                    double hx = value / 2.0;
                    double ox = OffsetX;
                    x1 = hx - ox;
                    x2 = hx + ox;
                    OnPropertyChanged("X1");
                    OnPropertyChanged("X2");
                    OnPropertyChanged("X");
                }
            }
            public double OffsetX
            {
                get { return (x2 - x1) / 2.0; }
                set
                {
                    double hx = X / 2.0;
                    double ox = value;
                    x1 = hx - ox;
                    x2 = hx + ox;
                    OnPropertyChanged("X1");
                    OnPropertyChanged("X2");
                    OnPropertyChanged("OffsetX");
                }
            }
            #endregion
    }
    I wan to change all of these proerties(X1,X2,X,Offset) to DependencyProperty 
    and keep these relationes.
    Does anyone know?

    thanks very much

    2009年9月7日 10:44

答案

  • Eh, perhaps you may try data binding, or try to add DependencyObject.InvalidProperty method call in your property.

    I just tried data binding approach, below is my code. The tricky is use multiple binding and IMultiValueConverter:
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
                TestClass tc = new TestClass();
                tc.X1 = 1;
                tc.X = 2.4;
            }
        }
    
        public class TestClass : DependencyObject
        {
            public double X1
            {
                get { return (double)GetValue(X1Property); }
                set { SetValue(X1Property, value); }
            }
    
            public static readonly DependencyProperty X1Property =
                DependencyProperty.Register("X1", typeof(double), typeof(TestClass), new UIPropertyMetadata(0.0));
    
            public double X2
            {
                get { return (double)GetValue(X2Property); }
                set { SetValue(X2Property, value); }
            }
    
            public static readonly DependencyProperty X2Property =
                DependencyProperty.Register("X2", typeof(double), typeof(TestClass), new UIPropertyMetadata(0.0));
    
            public double X
            {
                get { return (double)GetValue(XProperty); }
                set { SetValue(XProperty, value); }
            }
    
            public static readonly DependencyProperty XProperty =
                DependencyProperty.Register("X", typeof(double), typeof(TestClass), new UIPropertyMetadata(0.0));
    
            public double OffsetX
            {
                get { return (double)GetValue(OffsetXProperty); }
                set { SetValue(OffsetXProperty, value); }
            }
    
            public static readonly DependencyProperty OffsetXProperty =
                DependencyProperty.Register("OffsetX", typeof(double), typeof(TestClass), new UIPropertyMetadata(0.0));
    
            public TestClass()
            {
                MultiBinding binding = new MultiBinding();
                binding.Bindings.Add(new Binding("X1")
                {
                    RelativeSource = RelativeSource.Self,
                    Mode = BindingMode.TwoWay
                });
                binding.Bindings.Add(new Binding("X2")
                {
                    RelativeSource = RelativeSource.Self,
                    Mode = BindingMode.TwoWay
                });
                binding.Converter = new X1X2ToXConverter();
                binding.Mode = BindingMode.TwoWay;
                binding.ConverterParameter = this;
                BindingOperations.SetBinding(this, XProperty, binding);
    
                binding = new MultiBinding();
                binding.Bindings.Add(new Binding("X1")
                {
                    RelativeSource = RelativeSource.Self,
                    Mode = BindingMode.TwoWay
                });
                binding.Bindings.Add(new Binding("X2")
                {
                    RelativeSource = RelativeSource.Self,
                    Mode = BindingMode.TwoWay
                });
                binding.Converter = new X1X2ToOffsetXConverter();
                binding.Mode = BindingMode.TwoWay;
                binding.ConverterParameter = this;
                BindingOperations.SetBinding(this, OffsetXProperty, binding);
            }
        }
    
        public class X1X2ToXConverter : IMultiValueConverter
        {
            #region IMultiValueConverter Members
    
            public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return (double)values[0] + (double)values[1];
            }
    
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
            {
                double hx = (double)value / 2.0;
                var tc = parameter as TestClass;
                double ox = tc.OffsetX;
                var result = new object[] {
                    hx - ox,
                    hx + ox};
    
                return result;
            }
    
            #endregion
        }
    
        public class X1X2ToOffsetXConverter : IMultiValueConverter
        {
            #region IMultiValueConverter Members
    
            public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return ((double)values[1] - (double)values[0]) / 2.0;
            }
    
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
            {
                double hx = ((TestClass)value).X / 2.0;
                double ox = (double)value;
                var result = new object[] {
                    hx - ox,
                    hx + ox};
    
                return result;
            }
    
            #endregion
        }
    • 已标记为答案 Maxi247 2009年10月6日 9:32
    2009年9月17日 16:55

全部回复

  • Hi Maxi247,

    First of all, sorry for the late response.
    You can use the CoerceValueCallback and PropertyChangedCallback to achieve the logic defined in the Set and Get accessor of normal .NET properties,  but please note that you can not directly write them in the wrapper (Get/Set) of dependency property, this is because of the XAML parsing mechanism, any procedural operations in the wrapper will be neglected in the parsing process.
    As a kindly reminder, since this is Chinese WPF forum, most of the community members are native Chinese, so when you are writting the post in English, I am afraid there will not more prompt feedbacks associated with you thread. Of course, if you are willing to post it in English, you can post it on the English version WPF forum.

    Thanks.
    Sincerely.

    Jim Zhou -MSFT
    2009年9月11日 8:03
    版主
  • Hi Jim

    yes I know these methods but my question is how?
    because they will be infinity circle when i use CoerceValueCallback and PropertyChangedCallback .
    Could you resolve the  infinity circle .
    Could you give me some code.
    thank you

    when i first use the form it is english version


    thanks

    2009年9月11日 14:29
  • Eh, perhaps you may try data binding, or try to add DependencyObject.InvalidProperty method call in your property.

    I just tried data binding approach, below is my code. The tricky is use multiple binding and IMultiValueConverter:
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
                TestClass tc = new TestClass();
                tc.X1 = 1;
                tc.X = 2.4;
            }
        }
    
        public class TestClass : DependencyObject
        {
            public double X1
            {
                get { return (double)GetValue(X1Property); }
                set { SetValue(X1Property, value); }
            }
    
            public static readonly DependencyProperty X1Property =
                DependencyProperty.Register("X1", typeof(double), typeof(TestClass), new UIPropertyMetadata(0.0));
    
            public double X2
            {
                get { return (double)GetValue(X2Property); }
                set { SetValue(X2Property, value); }
            }
    
            public static readonly DependencyProperty X2Property =
                DependencyProperty.Register("X2", typeof(double), typeof(TestClass), new UIPropertyMetadata(0.0));
    
            public double X
            {
                get { return (double)GetValue(XProperty); }
                set { SetValue(XProperty, value); }
            }
    
            public static readonly DependencyProperty XProperty =
                DependencyProperty.Register("X", typeof(double), typeof(TestClass), new UIPropertyMetadata(0.0));
    
            public double OffsetX
            {
                get { return (double)GetValue(OffsetXProperty); }
                set { SetValue(OffsetXProperty, value); }
            }
    
            public static readonly DependencyProperty OffsetXProperty =
                DependencyProperty.Register("OffsetX", typeof(double), typeof(TestClass), new UIPropertyMetadata(0.0));
    
            public TestClass()
            {
                MultiBinding binding = new MultiBinding();
                binding.Bindings.Add(new Binding("X1")
                {
                    RelativeSource = RelativeSource.Self,
                    Mode = BindingMode.TwoWay
                });
                binding.Bindings.Add(new Binding("X2")
                {
                    RelativeSource = RelativeSource.Self,
                    Mode = BindingMode.TwoWay
                });
                binding.Converter = new X1X2ToXConverter();
                binding.Mode = BindingMode.TwoWay;
                binding.ConverterParameter = this;
                BindingOperations.SetBinding(this, XProperty, binding);
    
                binding = new MultiBinding();
                binding.Bindings.Add(new Binding("X1")
                {
                    RelativeSource = RelativeSource.Self,
                    Mode = BindingMode.TwoWay
                });
                binding.Bindings.Add(new Binding("X2")
                {
                    RelativeSource = RelativeSource.Self,
                    Mode = BindingMode.TwoWay
                });
                binding.Converter = new X1X2ToOffsetXConverter();
                binding.Mode = BindingMode.TwoWay;
                binding.ConverterParameter = this;
                BindingOperations.SetBinding(this, OffsetXProperty, binding);
            }
        }
    
        public class X1X2ToXConverter : IMultiValueConverter
        {
            #region IMultiValueConverter Members
    
            public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return (double)values[0] + (double)values[1];
            }
    
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
            {
                double hx = (double)value / 2.0;
                var tc = parameter as TestClass;
                double ox = tc.OffsetX;
                var result = new object[] {
                    hx - ox,
                    hx + ox};
    
                return result;
            }
    
            #endregion
        }
    
        public class X1X2ToOffsetXConverter : IMultiValueConverter
        {
            #region IMultiValueConverter Members
    
            public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return ((double)values[1] - (double)values[0]) / 2.0;
            }
    
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
            {
                double hx = ((TestClass)value).X / 2.0;
                double ox = (double)value;
                var result = new object[] {
                    hx - ox,
                    hx + ox};
    
                return result;
            }
    
            #endregion
        }
    • 已标记为答案 Maxi247 2009年10月6日 9:32
    2009年9月17日 16:55
  • thank you very much.

    it's a good idea
    2009年10月6日 9:33