Chaining DependencyProperties - PullRequest
       7

Chaining DependencyProperties

6 голосов
/ 14 декабря 2011

Допустим, у меня есть пользовательский элемент управления, который оборачивает другой элемент управления (например, MyCustomButton).Я раскрываю свойство Content, которое оборачивает внутренний элемент управления:

    public object Content
    {
        get { return innerControl.Content; }
        set { innerControl.Content = value; }
    }

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

 public static DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof (object), typeof (MyCustomButton));

но теперь мне нужно мое определение свойства, чтобы использовать GetValue / SetValue:

    public object Content
    {
        get { return GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

, поэтому я больше не оборачиваю значение внутреннего элемента управления.

Я могу определить PropertyMetadata для обработки PropertyChangedсобытие DependencyProperty, но затем мне нужен набор кода для синхронизации значений и предотвращения бесконечных зацикливаний при изменении.

ОБНОВЛЕНИЕ: я не могу просто получить из Button, потому что мой UserControl имеет различные другие проблемы.

Есть ли лучший способ сделать это?

1 Ответ

2 голосов
/ 14 декабря 2011

Ну, в зависимости от того, почему вы оборачиваете кнопку пользовательским элементом управления, вы можете определить пользовательский элемент управления, который наследуется от кнопки.Затем, вместо переноса кнопки и предоставления нужных упакованных методов и свойств, вы можете просто переопределить методы и свойства, поведение которых вы хотите определить для пользовательского элемента управления.Таким образом, вы получите все функциональные возможности кнопки без необходимости заново изобретать колесо.

Вот ссылка Google, которая проведет вас по ней (одна из первых, которую я нашел - их много):http://knol.google.com/k/creating-custom-controls-with-c-net#

Если у пользовательского элемента управления есть другие проблемы, это может быть не вариант для вас, но я предлагаю этот ответ, потому что единственная цель, которую вы упомянули для этого, - это завернуть кнопку.Я лично предпочел бы создать пользовательский элемент управления и наследовать, а не пользовательский элемент управления и перенос, если рассматриваемый элемент управления просто предназначен для более специфического вида упакованного / унаследованного элемента управления (т. Е. Кнопки в вашем случае).* Изменить: В свете обновленного вопроса ...

Вы могли бы сделать что-то в этом роде.Вот XAML клиента вашего пользовательского элемента управления:

<Grid>
    <local:MyControl ButtonContent="Click Me!"/>
</Grid>
</Window>

Вот XAML для самого пользовательского элемента управления:

 <UserControl x:Class="GuiScratch.MyControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:GuiScratch"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>

        <StackPanel>
            <ContentControl Content="Asdf"/>
            <Button Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyControl}},Path=ButtonContent}"/>
        </StackPanel>

    </Grid>
</UserControl>

И вот код:

public partial class MyControl : UserControl
{

    public static readonly DependencyProperty ButtonContentProperty = 
    DependencyProperty.Register("ButtonContent", typeof(object), typeof(MyControl), 
    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));

    public object ButtonContent
    {
        get { return (object)GetValue(ButtonContentProperty); }
        set { SetValue(ButtonContentProperty, value); }
    }

    public MyControl()
    {
        InitializeComponent();
    }
}

Итак, вам вообще не нужно обрабатывать привязку через код.Ваш клиентский XAML привязывается к вашему свойству зависимости, как и XAML самого пользовательского элемента управления.Таким образом они разделяют настройку свойства зависимостей.Я запустил это в своем маленьком блокноте, и в результате (по крайней мере, мое понимание), что вы ищете.В главном окне пользовательский элемент управления отображается в виде панели стека с текстом «Asdf», а затем с кнопкой «Click Me!»

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