从父控件设置WPF嵌套控件属性

时间:2009-03-25 21:56:46

标签: .net wpf xaml

我有一个WPF窗口,上面有多个ListBox控件,所有这些都与我在这里简化的样式共享:

   <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>

以下是使用该样式的ListBox控件之一的示例:

<ListBox x:Name="lbCampaigns" Button.Click="lbCampaigns_Click" ItemsSource="{Binding}" Style="{StaticResource listBox}" />

如何在父ListBox中设置Button控件的内容(btnGet)?

我知道我希望按钮在设计时为Window上的每个ListBox显示什么文本。 (即我不需要将它绑定到ListBox ItemsSource)。我看到我可以定义子控件的事件(参见Button.Click定义),但似乎我不能以相同的方式设置子控件的属性。

有什么想法吗? 谢谢!

1 个答案:

答案 0 :(得分:8)

Button.Click的设置未将事件处理程序分配给Button。它正在将其分配给ListBox。它的工作原理是因为WPF的路由事件系统。

如果您希望Button采用ListBox级别设置的值,则在这种情况下,一个选项是Binding使用RelativeSource

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

在这种情况下,我刚刚劫持了Tag属性,您可以按如下方式指定:

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

另一种选择是使用继承的附加属性。例如:

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

然后:

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

最后,如果您正在模仿ListBox本身,您可以“伸出”并使用TemplateBinding绑定到您正在模板化的控件的属性:

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

当然,这种技术通常与模板化控件上特别声明的属性一起使用。例如,您可以继承ListBox并添加自己的ButtonContent属性。然后,在您的模板中,您可以伸出并从Button绑定到该属性。