Search code examples
c#wpfvisual-studiobindingdependency-properties

Passing Property Values from Parent UserControl to Child's DependencyProperty


How to pass property (SomeProperty) from ParentUserControl context to DependencyProperty (MyDProperty) of the ChildUserControl?

In XAML, it should be: <uc:ChildUserControl MyDProperty="{Binding SomeProperty}"> but, for some reason, MyDProperty never gets set with Parent.DataContext.SomeProperty.

In my case, I'm passing an Action, but that's not important. I think the issue lies in the binding.


ParentUserControl:

    public Action RemoveEsl1 => throw new NotImplementedException();

    <uc:ChildUserControl Title="ESL 1" RemoveEslAction="{Binding RemoveEsl1}" DataContext="{Binding Esl1}"/>

ChildUserControl:

    public static readonly DependencyProperty RemoveEslActionProperty =
        DependencyProperty.Register(nameof(RemoveEslAction), typeof(Action), typeof(ChildUserControl), new PropertyMetadata(delegate { }));


    public Action RemoveEslAction
    {
        get => (Action)GetValue(RemoveEslActionProperty);
        set => SetValue(RemoveEslActionProperty, value);
    }

I found various tips here, but none of them either suited me or worked.


Solution

  • Answering my own question (check ParentUserControl):

    Models:

    public class RootModel : ViewModelBase
    {
        private ParentModel parentModel = new();
        public ParentModel ParentModel { get => parentModel; set => RisePropertyChanged(ref parentModel, value); }
    }
    
    public class ParentModel : ViewModelBase
    {
        private ChildModel childModel = new();
        public ChildModel ChildModel { get => childModel; set => RisePropertyChanged(ref childModel, value); }
    
        public string ParentModelProperty => "Correct value from ParentModel";
    }
    
    public class ChildModel : ViewModelBase
    {
        private string childModelProperty = "Wrong default value from ChildModel";
        public string ChildModelProperty { get => childModelProperty; set => RisePropertyChanged(ref childModelProperty, value); }
    }
    

    MainWindow:

    <Window.DataContext>
        <model:RootModel/>
    </Window.DataContext>
    
    <uc:ParentUserControl DataContext="{Binding ParentModel}"/>
    

    ParentUserControl:

    <uc:ChildUserControl ChildDependency="{Binding DataContext.ParentModelProperty, RelativeSource={RelativeSource AncestorType=UserControl}}" DataContext="{Binding ChildModel}"/>
    

    ChildUserControl:

    <StackPanel>
        <Label Content="Dependency property:"/>
        <Label Content="{Binding ChildDependency, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
        <Separator/>
        <Label Content="Property:"/>
        <Label Content="{Binding ChildModelProperty}"/>
    </StackPanel>
    
    
    public partial class ChildUserControl : UserControl
    {
        public static readonly DependencyProperty ChildDependencyProperty =
            DependencyProperty.Register(nameof(ChildDependency), typeof(string), typeof(ChildUserControl), new ("Wrong default DP value from ChildUserControl"));
    
        public string ChildDependency
        {
            get => (string)GetValue(ChildDependencyProperty);
            set => SetValue(ChildDependencyProperty, value);
        }
    
        public ChildUserControl()
        {
            InitializeComponent();
        }
    }
    

    So this is how to pass a property (ParentModelProperty) from ParentUserControl context to DependencyProperty (ChildDependency) of the ChildUserControl.