Как связать или ссылаться на UserControl из другого UserControl в WPF? - PullRequest
0 голосов
/ 29 октября 2019

В моем приложении у меня есть UserControl, который содержит еще один UserControl, например:

<UserControl x:Class="FooControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MyApp">
    <local:BarControl x:Name="NestedControl" />
</UserControl>

Теперь в пределах размещенного BarControl я хочу вычислить его положение, относительнона хостинг FooControl контроль. В настоящее время я вызываю элемент дочернего элемента управления из кода FooControl s, например:

this.NestedControl.ComputeRelativePos(this);

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

public void ComputeRelativePos(Control relativeTo)
{
    var pos = this.TranslatePoint(new System.Windows.Point(0, 0), relativeTo);

    // ...
}

Теперь я хочу исключить этот вызов и пересчитать позицию из обработчиков событий (например, SizeChanged) вложенного BarControl. Я хочу сделать это, чтобы BarControl не требовал размещения в FooControl или другом элементе управления, явно вызывая ComputeRelativePos:

public BarControl()
{
    this.InitializeComponent();
    this.SizeChanged += (sender, args) => 
    {
        this.ComputeRelativePos(this.OuterControl);
    };
}

Однако я не совсем уверен, каксоздайте привязку для свойства OuterControl. Я определил свойство следующим образом:

public Control OuterControl
{
    get { return this.GetValue(OuterControlProperty) as Control; }
    set { this.SetValue(OuterControlProperty, value); }
}

public static readonly DependencyProperty OuterControlProperty = 
    DependencyProperty.Register("OuterControl", typeof(Control), typeof(BarControl), new UIPropertyMetadata(null));

и определил привязку в разметке FooControl следующим образом:

<local:BarControl x:Name="NestedControl" OuterControl="{Binding RelativeSource={RelativeSource Self}}" />

, но OuterControl, по-видимому, не установленправильно:

this.SizeChanged += (sender, args) => this.ComputeRelativePos(this.OuterControl); // this.OuterControl is `null`

Я также пытался связать с FooControl именем экземпляра 1 :

<local:BarControl x:Name="NestedControl" 
    OuterControl="{Binding RelativeSource={RelativeSource Self}, Path=Name}" />

..., чтобы я мог запросить его извизуальное дерево (как предложено здесь ), но оно также не сработало.

Итак, мой общий вопрос: как мне получить доступ к родительскому элементу управления, который привязан к свойству ребенка? Я также согласился бы с альтернативным подходом к этой проблеме, так как я довольно неопытен с XAML / WPF.

Заранее спасибо. 10

1 И, конечно, определение DependencyProperty соответственно.

1 Ответ

1 голос
/ 29 октября 2019

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

<local:BarControl x:Name="NestedControl" 
OuterControl="{Binding RelativeSource={RelativeSource Self}, Path=Name}" />

на:

<local:BarControl x:Name="NestedControl" OuterControl="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />

Когда это будет сказано, измененный размер вашего обработчика событий будет изменен до того, как будет установлен контроль зависимостей. Свойства зависимостей устанавливаются после инициализации элемента управления.

Но потом, когда вы измените размер, вы увидите, что относительное значение установлено на FooControl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...