Создание привязываемой точки в C # WPF - PullRequest
7 голосов
/ 24 февраля 2011

Я знаю, что множественное наследование отсутствует, но есть ли способ создать оболочку для System.Windows.Point, которая может наследовать от него, но при этом реализовать свойства привязываемой зависимости?

Я пытаюсь так закодироватьчто для моего XAML я могу без проблем создавать такие позиции, как следующие:

<custom:Point X="{Binding Width, ElementName=ParentControlName}" Y="{Binding Height, ElementName=ParentControlName}" />

Это значительно упростит кодирование таких объектов, как полигоны, пути, линейные сегменты и другие элементы управления.

Следующий код предоставлен как желаемое за действительное, и я понимаю, что он никоим образом не сработает, но я хочу, чтобы я смог это сделать:

</p> <pre><code>public class BindablePoint: DependencyObject, Point { public static readonly DependencyProperty XProperty = DependencyProperty.Register("X", typeof(double), typeof(BindablePoint), new FrameworkPropertyMetadata(default(double), (sender, e) => { BindablePoint point = sender as BindablePoint; point.X = (double) e.NewValue; })); public static readonly DependencyProperty YProperty = DependencyProperty.Register("Y", typeof(double), typeof(BindablePoint), new FrameworkPropertyMetadata(default(double), (sender, e) => { BindablePoint point = sender as BindablePoint; point.Y = (double)e.NewValue; })); public new double X { get { return (double)GetValue(XProperty); } set { SetValue(XProperty, value); base.X = value; } } public new double Y { get { return (double)GetValue(YProperty); } set { SetValue(YProperty, value); base.Y = value; } } }

Ответы [ 4 ]

4 голосов
/ 24 февраля 2011

К сожалению, Point является структурой, и структуры не поддерживают наследование. От MSDN

Примечание Структуры не поддерживают наследование, но они могут реализовать интерфейсы. Для получения дополнительной информации см. Интерфейсы (Руководство по программированию в C #) .

Возможно, это не отвечает на ваш вопрос напрямую, но вы можете легко связать Point с помощью конвертера. В вашем случае это будет похоже на

<SomeControl.SomePointProperty>
    <MultiBinding Converter="{StaticResource PointConverter}">
        <Binding ElementName="ParentControlName"
                 Path="Width"/>
        <Binding ElementName="ParentControlName"
                 Path="Height"/>
    </MultiBinding>                                        
</SomeControl.SomePointProperty>

PointConverter

public class PointConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double xValue = (double)values[0];
        double yValue = (double)values[1];
        return new Point(xValue, yValue);
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Если вы просто хотите связать значение X и иметь статическое значение Y, вы можете сделать это как

<SomeControl SomePointProperty="{Binding Path=Width,
                                         ElementName=ParentControlName,
                                         Converter={StaticResource PointXConverter},
                                         ConverterParameter=20}"/>

PointXConverter

public class PointXConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double progressBarValue = (double)value;
        double yValue = System.Convert.ToDouble(parameter);
        return new Point(progressBarValue, yValue);
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
} 
0 голосов
/ 19 августа 2015
  1. Написать класс-оболочку для точки, которая реализует интерфейс INotifyPropertyChanged

    public class BindingPoint : INotifyPropertyChanged
    {
        private Point point;
    
        public BindingPoint(double x, double y)
        {
            point = new Point(x, y);
        }
    
        public double X
        {
            get { return point.X; }
            set
            {
                point.X = value;
                OnPropertyChanged();
                OnPropertyChanged("Point");
            }
        }
    
        public double Y
        {
            get { return point.Y; }
            set
            {
                point.Y = value;
                OnPropertyChanged();
                OnPropertyChanged("Point");
            }
        }
    
        public Point Point
        {
            get { return point; }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
  2. Привязка свойств X и Y начальной точки / конечной точки, например, к экземпляру строки

    Line line = new Line();
    BindingPoint startPoint = new BindingPoint(0,0);
    BindingPoint endPoint = new BindingPoint(0,0);
    
    var b = new Binding("X")
    {
        Source = startPoint,
        Mode = BindingMode.TwoWay
    };
    line.SetBinding(Line.X1Property, b);
    
    b = new Binding("Y")
    {
        Source = startPoint,
        Mode = BindingMode.TwoWay
    };
    line.SetBinding(Line.Y1Property, b);
    
    b = new Binding("X")
    {
        Source = endPoint,
        Mode = BindingMode.TwoWay
    };
    line.SetBinding(Line.X2Property, b);
    
    b = new Binding("Y")
    {
        Source = endPoint,
        Mode = BindingMode.TwoWay
    };
    line.SetBinding(Line.Y2Property, b);
    
0 голосов
/ 24 февраля 2011

Возможно, вам придется переопределить все классы (Point, Polygon, Line и т. Д.) С нуля, поскольку Point - это структура, поэтому она не поддерживает наследование (что также объясняет, почему Point не поддерживает привязку: он не может наследовать DependencyObject, который содержит необходимую инфраструктуру для DP).

Хотя может быть способ - вы можете создать подкласс polygon и добавить новый DependencyProperty с именем "BindablePoints", который будет наблюдаемой коллекцией (вам придется создать собственный OC, который будет запускать CollectionChanged когда одна из точек изменилась) из точек. Свойство OnChanged будет обновлять основное Points свойство Polygon.

Полагаю, это может сработать, но я не уверен, будет ли это достаточно быстро для всего, что вы пытаетесь сделать. Вам все равно придется создавать подклассы всех форм, которые вы хотите использовать, но вам не придется создавать их все с нуля.

0 голосов
/ 24 февраля 2011

Попробуйте использовать Преобразователи вместо.

...