Search code examples
wpfxamluser-controlselementname

Wpf, How to find Element name from one user control in another


    <TextBox x:Name="DescriptionTextBox" 
             Text="{Binding SelectedEntity.Description,
                            ValidatesOnExceptions=True}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="LostFocus" SourceName="DescriptionTextBox">
                <ei:CallMethodAction MethodName="RaiseCanExecuteChanged" 
                TargetObject="{Binding Command, ElementName=SaveButton}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>

    <userControls:SaveCloseUserControl />

Inside this user control

<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
    <Button Width="50"
            Command="{Binding SaveCommand}"
            Content="Save" />
    <Button Width="50"
            Command="{Binding CloseCommand}"
            Content="Close" />
 </StackPanel>

The problem here is that this TargetObject="{Binding Command, ElementName=SaveButton}" does not find SaveButton because its inside of userControls:SaveCloseUserControl I looked online and I found a solution (from 2009) that required code behind, is there not an easy way of doing this stuff today? Regards

Edit

Based on @huzle answer I did this in the code behind of the user control

    public object CreateButton { get { return CreateChild; } }

and in xaml i added a name to the save button.

so the my final version looks like this

    <TextBox x:Name="DescriptionTextBox" 
             Text="{Binding SelectedEntity.Description,
                            ValidatesOnExceptions=True}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="LostFocus" SourceName="DescriptionTextBox">
                <ei:CallMethodAction MethodName="RaiseCanExecuteChanged" 
                TargetObject="{Binding CreateButton.Command,ElementName=MySaveCloseUserControl}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>

    <userControls:SaveCloseUserControl x:Name="MySaveCloseUserControl"/>

Solution

  • Give your "SaveCloseUserControl" a public properties for the "SaveButton" named "InnerSaveButton" and bind with ElementName to your SaveCloseUserControl and use the Path for getting to the Command of your inner button.

    <TextBox x:Name="DescriptionTextBox" 
             Text="{Binding SelectedEntity.Description,
                            ValidatesOnExceptions=True}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="LostFocus" SourceName="DescriptionTextBox">
                <ei:CallMethodAction MethodName="RaiseCanExecuteChanged" 
                TargetObject="{Binding InnerSaveButton.Command, ElementName=MySaveCloseUserControl}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>
    
    <userControls:SaveCloseUserControl X:Name="MySaveCloseUserControl"/>