Click here to Skip to main content
15,888,062 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How do I Bind to elements in the Main Window from an element in a UserControl that has been added to the window

<Window x:Class="WpfApplication1.MainWindow"
        xmlns:local="clr-namespace:WpfApplication1">
    <Grid x:Name="LayoutRootGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="100"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock x:Name="FirstNameTextBlock" Grid.Row="0"
                 Text="John"/>
        <TextBox x:Name="LastNameTextBlock" Grid.Row="1"
                 Text="Smith"/>
        <local:SecondControl x:Name="SecondControl" Grid.Row="2"/>
    </Grid>
</Window>


The custom user control is like below

<UserControl x:Class="WpfApplication1.SecondControl">
    <StackPanel Background="CadetBlue">
        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top"
                   Text="{Binding ElementName=FirstNameTextBlock, Path=Text}" />
        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top"
                   Text="{Binding ElementName=LastNameTextBlock, Path=Text}" />
    </StackPanel>
</UserControl>


The above binding setup did not work...What am I doing wrong?

Just started learning WPF...

Thanks for your help!
Posted
Updated 17-Feb-14 13:22pm
v4
Comments
Sergey Alexandrovich Kryukov 17-Feb-14 19:47pm    
It depends on what you are trying to achieve, exactly.
—SA
debuggd 17-Feb-14 19:56pm    
Im just trying to know how binding works in the above simple scenario. Please see my code.
Sergey Alexandrovich Kryukov 17-Feb-14 20:24pm    
You did not get my hint. Before showing your code, it's good to tell us what are your ultimate goals.
—SA
debuggd 17-Feb-14 21:03pm    
I wish I had a good answer to that. I am not working with a real world application. I am a newbie just testing binding scenarios in small applications. So I created an app that had the above requirements and wanted to see what if there was a situation like this, how do I setup binding.
Sergey Alexandrovich Kryukov 17-Feb-14 21:15pm    
You cannot do anything sensible if you don't understand that goals. And if you do understand them, you can explain... Otherwise, there is nothing to help with...
—SA

1 solution

You can't do this directly.
The Window and SecondControl are two different contexts (WPF XAML NameScope) and the ElementName is limited by NameScope.
"You can refer to elements in code only if they are registered to the appropriate NameScope"
MSDN: Binding.ElementName[^]

So, I see two possibilities:
1. If the FirstNameTextBlock/LastNameTextBlock controls of the Window are NOT "hardcoded", but are instead data bound to the Window's DataContext, then the SecondControl can use the same binding descriptions, since it has inherited the DataContext from the Window:
HTML
<Window x:Class="WpfApplication1.MainWindow"
        xmlns:local="clr-namespace:WpfApplication1">
    <Grid x:Name="LayoutRootGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="100"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock x:Name="FirstNameTextBlock" Grid.Row="0"
                 Text="{Binding Path=FirstName}"/>
        <TextBox x:Name="LastNameTextBlock" Grid.Row="1"
                 Text="{Binding Path=LastName}"/>
        <local:SecondControl x:Name="SecondControl" Grid.Row="2"/>
    </Grid>
</Window>

<UserControl x:Class="WpfApplication1.SecondControl">
    <StackPanel Background="CadetBlue">
        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top"
                   Text="{Binding Path=FirstName}" />
        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top"
                   Text="{Binding Path=LastName}" />
    </StackPanel>
</UserControl>

2. (and probably better) would be to have the SecondControl contain DependencyProperties that can take the binding where the SecondControl is used in the Window:
HTML
<Window x:Class="WpfApplication1.MainWindow"
        xmlns:local="clr-namespace:WpfApplication1">
    <Grid x:Name="LayoutRootGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="100"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock x:Name="FirstNameTextBlock" Grid.Row="0"
                 Text="John"/>
        <TextBox x:Name="LastNameTextBlock" Grid.Row="1"
                 Text="Smith"/>
        <local:SecondControl x:Name="SecondControl" Grid.Row="2"
                             FirstName="{Binding ElementName=FirstNameTextBlock, Path=Text}"
                             LastName="{Binding ElementName=LastNameTextBlock, Path=Text}" />
    </Grid>
</Window>

<UserControl x:Class="WpfApplication1.SecondControl" x:Name="SecondControl" >
    <StackPanel Background="CadetBlue">
        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top"
                   Text="{Binding ElementName=SecondControl, Path=FirstName}" />
        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top"
                   Text="{Binding ElementName=SecondControl, Path=LastName}" />
    </StackPanel>
</UserControl>

In SecondControl.xaml.cs:
C#
public static readonly DependencyProperty FirstNameProperty =
    DependencyProperty.Register("FirstName", typeof(string), typeof(SecondControl), new UIPropertyMetadata(string.Empty));

public string FirstName
{
  get { return (string)GetValue(FirstNameProperty); }
  set { SetValue(FirstNameProperty, value); }
}

public static readonly DependencyProperty LastNameProperty =
    DependencyProperty.Register("LastName", typeof(string), typeof(SecondControl), new UIPropertyMetadata(string.Empty));

public string LastName
{
  get { return (string)GetValue(LastNameProperty); }
  set { SetValue(LastNameProperty, value); }
}
 
Share this answer
 
Comments
debuggd 17-Feb-14 21:27pm    
Matt, thanks so much!

Option 1 works and I understand it!

Option 2 I implemented but for some reason, it still did not work. I just updated SecondControl xaml and code behind with the code you pasted above. I believe that should be enough but am I missing something?
Matt T Heffron 18-Feb-14 12:30pm    
You're welcome!
Please formally "Accept" the solution (and rate it as you see fit).
I'm not totally surprised about Option 2. It might need a bit of tweaking.
I just put the code here, "off the top of my head", I didn't try it. :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900