Связывание двух свойств зависимостей из двух разных пользовательских элементов управления - PullRequest
0 голосов
/ 30 июня 2018

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

Первый - это простой пользовательский элемент управления с прикрепленным к нему большим пальцем, большой палец заставляет элемент управления перемещаться, перетаскивая его, это просто и работает.

XAML:

<Canvas>
    <Thumb x:Name="Thumb" Width="15" Height="15" DragDelta="Thumb_DragDelta"/>
</Canvas>

Code-Behind: свойство зависимости с именем Position , когда вызывается Setter, оно обновляет поле usercontrol.

public partial class ThumbPoint : UserControl
{
    public Point Position
    {
        get { return (Point)GetValue(PositionProperty); }
        set { SetValue(PositionProperty, value); this.Margin = new Thickness(value.X, value.Y, 0, 0); }
    }

    // Using a DependencyProperty as the backing store for Position.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PositionProperty =
        DependencyProperty.Register("Position", typeof(Point), typeof(ThumbPoint), new PropertyMetadata(new Point()));

    public ThumbPoint()
    {
        InitializeComponent();
        Position = new Point(0, 0);
    }

    private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
    {
        Position = new Point(Position.X + e.HorizontalChange, Position.Y + e.VerticalChange);
    }
}

Второй UserControl называется StraightLine, он состоит из элемента управления Line

XAML:

<Canvas>
    <Line x:Name="Line" Stroke="Gray" StrokeThickness="1"/>
</Canvas>

Code-Behind: свойство зависимости с именем StartPosition , когда вызывается Setter, оно обновляет строки X1 и Y1 (начальная позиция строки).

public partial class StraightLine : UserControl
{
    public Point StartPosition
    {
        get { return (Point)GetValue(StartPositionProperty); }
        set { SetValue(StartPositionProperty, value); Line.X1 = value.X; Line.Y1 = value.Y; }
    }

    // Using a DependencyProperty as the backing store for StartPosition.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty StartPositionProperty =
        DependencyProperty.Register("StartPosition", typeof(Point), typeof(StraightLine), new PropertyMetadata(new Point()));

    public StraightLine()
    {
        InitializeComponent();

        Line.X1 = 0;
        Line.Y1 = 0;

        Line.X2 = 300;
        Line.Y2 = 200;
    }
}

Здесь я пытаюсь связать их вместе в mainwindow.xaml:

<Canvas>
    <local:ThumbPoint x:Name="ThumbPoint"/>
    <local:StraightLine StartPosition="{Binding Position, ElementName=ThumbPoint}"/>
</Canvas>

Желаемый эффект: DependencyProperty StartPosition линии StraightLine должен быть обновлен.

Что происходит: оно не обновляется, поэтому движется только ThumbPoint.

1 Ответ

0 голосов
/ 30 июня 2018
Привязка

не использует обертки общих свойств для DP (public Point StartPosition), она использует SetValue() напрямую, поэтому код в установщике не вызывается.

Что необходимо, это propertyChangedCallback:

public Point StartPosition
{
    get { return (Point)GetValue(StartPositionProperty); }
    set { SetValue(StartPositionProperty, value); }
}

public static readonly DependencyProperty StartPositionProperty =
    DependencyProperty.Register("StartPosition", typeof(Point), typeof(StraightLine), new PropertyMetadata(new Point(), OnStartPositionChanged));

private static void OnStartPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{
   StraightLine c = (StraightLine) d;
   c.Line.X1 = c.StartPosition.X; 
   c.Line.Y1 = c.StartPosition.Y; 
}

в ThumbPoint public Point Position свойство имеет ту же проблему, но оно работает там, потому что вы используете setter напрямую: Position = new Point()

В качестве альтернативы можно связать значения X1 и Y1 в xaml:

<Canvas>
    <Line x:Name="Line" Stroke="Gray" StrokeThickness="1"
          X1="{Binding StartPosition.X, RelativeSource={RelativeSource AncestorType=StraightLine}}"
          Y1="{Binding StartPosition.Y, RelativeSource={RelativeSource AncestorType=StraightLine}}"/>
</Canvas>

(или использовать ElementName вместо RelativeSource)

...