Setting WPF nested control properties from the parent control

.net, wpf, xaml

Solution

Your setting of `Button.Click` isn't assigning the event handler to the Button. It's assigning it to the `ListBox`. It works because of WPF's routed event system.

If you want the `Button` to take on a value set at the level of the `ListBox`, one option in this case is to use a `Binding` with a `RelativeSource`:

<Button Content="{Binding Tag, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}"/>

In this case I've just hijacked the `Tag` property, which you can specify as follows:

<ListBox Tag="This is the button's content" .../>

Another option is to use an inherited attached property. For example:

<Button Content="{Binding local:MyClass.MyAttachedProperty}"/>

And then:

<ListBox local:MyClass.MyAttachedProperty="This is the button's content"/>

Finally, if you were templating the `ListBox` itself, you can "reach out" and bind to a property of the control you're templating using a `TemplateBinding`:

<Button Content="{TemplateBinding Tag}"/>

Of course, this technique is generally used with properties specifically declared on the templated control. For example, you could subclass `ListBox` and add your own `ButtonContent` property. Then, in your template you could reach out and bind to that property from the `Button`.

Problem

I have a WPF window, with multiple ListBox controls on it, all sharing the same style that I've simplified here: ``` <Style x:Key="listBox" TargetType="{x:Type ListBox}"> <Setter Property="ItemTemplate"> <Setter.Value> <DataTemplate> <Border BorderBrush="Black"> <StackPanel Orientation="Horizontal" > <TextBlock Text="{Binding Path=name}" /> <TextBlock Text="{Binding Path=text}" /> <TextBlock Text="id:" /> <TextBlock x:Name="_idTextBlock" Text="{Binding Path=id}" /> <Button Name="btnGet" CommandParameter="{Binding Path=id}" /> </StackPanel> </Border> </DataTemplate> </Setter.Value> </Setter> </Style> ``` And here is an example of one of the ListBox controls using that style: ``` <ListBox x:Name="lbCampaigns" Button.Click="lbCampaigns_Click" ItemsSource="{Binding}" Style="{StaticResource listBox}" /> ``` How can I set the Content of the Button control (btnGet) from within the parent ListBox? I know what text I want the button to display at design time for each ListBox on the Window. (i.e. I don't need to bind it to the ListBox ItemsSource). I see that I can define the child control's events (see the Button.Click definition), but it doesn't appear that I can set the child control's properties in the same manner. Any ideas? Thanks!

Original source