Joseph Sturtevant
Joseph Sturtevant

Reputation: 13360

Expose DependencyProperty

When developing WPF UserControls, what is the best way to expose a DependencyProperty of a child control as a DependencyProperty of the UserControl? The following example shows how I would currently expose the Text property of a TextBox inside a UserControl. Surely there is a better / simpler way to accomplish this?

    <UserControl x:Class="WpfApplication3.UserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <StackPanel Background="LightCyan">
            <TextBox Margin="8" Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
        </StackPanel>
    </UserControl>
    using System;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace WpfApplication3
    {
        public partial class UserControl1 : UserControl
        {
            public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(UserControl1), new PropertyMetadata(null));
            public string Text
            {
                get { return GetValue(TextProperty) as string; }
                set { SetValue(TextProperty, value); }
            }
    
            public UserControl1() { InitializeComponent(); }
        }
    }

Upvotes: 18

Views: 8313

Answers (2)

some_engineer
some_engineer

Reputation: 1874

You can set DataContext to this in UserControl's constructor, then just bind by only path.

CS:

DataContext = this;

XAML:

<TextBox Margin="8" Text="{Binding Text} />

Upvotes: 1

user7116
user7116

Reputation: 64068

That is how we're doing it in our team, without the RelativeSource search, rather by naming the UserControl and referencing properties by the UserControl's name.

<UserControl x:Class="WpfApplication3.UserControl1" x:Name="UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel Background="LightCyan">
        <TextBox Margin="8" Text="{Binding Path=Text, ElementName=UserControl1}" />
    </StackPanel>
</UserControl>

Sometimes we've found ourselves making too many things UserControl's though, and have often times scaled back our usage. I'd also follow the tradition of naming things like that textbox along the lines of PART_TextDisplay or something, so that in the future you could template it out yet keep the code-behind the same.

Upvotes: 18

Related Questions