WPF GroupBox HeaderTemplate 和 DataBinding
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2425079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF GroupBox HeaderTemplate and DataBinding
提问by Coolweb
I define a headertemplate into a wpf groupbox and the databinding doesn't work. I don't understand why.
我将 headertemplate 定义到 wpf groupbox 中,并且数据绑定不起作用。我不明白为什么。
<GroupBox>
<GroupBox.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Image Source="/PopuAssuNetApplication.UI.Control;component/Images/Members.png" Width="24" />
<TextBlock VerticalAlignment="Center">
<TextBlock.Text>
<MultiBinding StringFormat="{x:Static Member=resx:Resources.PersonsInContractGroupBox}">
<Binding Path="CurrentContract.Federation" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}">
</Binding>
<Binding Path="CurrentContract.Type" Converter="{StaticResource contractTypeConverter}" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}">
</Binding>
<Binding Path="CurrentContract.Number" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}">
</Binding>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<WpfComponent:WaitControl Margin="7,0,0,0" VerticalAlignment="Top" Width="24" Height="24" MarginCenter="4">
<WpfComponent:WaitControl.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsMembersOfContractBusy, UpdateSourceTrigger=PropertyChanged, ElementName=PersonsInContract}" Value="true">
<Setter Property="WpfComponent:WaitControl.Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsMembersOfContractBusy, UpdateSourceTrigger=PropertyChanged, ElementName=PersonsInContract}" Value="false">
<Setter Property="WpfComponent:WaitControl.Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</WpfComponent:WaitControl.Style>
</WpfComponent:WaitControl>
</StackPanel>
</DataTemplate>
</GroupBox.HeaderTemplate>
采纳答案by gehho
The GroupBox does not have a member called "CurrentContract". Most probably, you want to accesss a property called "CurrentContract" from the corresponding ViewModel?! The ViewModel is the GroupBox's DataContext, so you have to change the Binding Paths to something like...
GroupBox 没有名为“CurrentContract”的成员。最有可能的是,您想从相应的 ViewModel 访问一个名为“CurrentContract”的属性?!ViewModel 是 GroupBox 的 DataContext,因此您必须将绑定路径更改为...
<Binding Path="DataContext.CurrentContract.Type" Converter="{StaticResource contractTypeConverter}" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}">
回答by jpierson
The problem is that the HeaderTemplate
is used for templating the Header thus within the HeaderTemplate
your DataContext
is whatever you bind or assign to the Header
property of your GroupBox
.
问题是HeaderTemplate
用于模板化 Header 因此在HeaderTemplate
your 中DataContext
是您绑定或分配给Header
您的GroupBox
.
Think of the Header
property as almost like the DataContext
for the header of the control. Normally the DataContext
property inhierits its value from its parent but since not every control has a Header
the Header is blank unless you set it.
将该Header
属性视为几乎类似于DataContext
控件标题的 。通常,该DataContext
属性从其父级继承其值,但由于并非每个控件都有一个Header
Header 为空,除非您设置它。
By binding your Header explicitly to the current DataContext Header="{Binding}"
your example should work as you expect. To help illustrate how this works I've created a simple example below that shows how the Header
and DataContext
work independently from each other for providing data to either the body or header of the control.
通过将您的 Header 显式绑定到当前 DataContext,Header="{Binding}"
您的示例应该可以按预期工作。为了帮助说明这是如何工作的,我在下面创建了一个简单的示例,该示例展示了Header
和DataContext
相互独立的工作,以便为控件的主体或标题提供数据。
<GroupBox Header="HEADER TEXT" DataContext="BODY TEXT">
<GroupBox.HeaderTemplate>
<DataTemplate>
<Button Content="{Binding}"
Background="LightGreen" />
</DataTemplate>
</GroupBox.HeaderTemplate>
<CheckBox HorizontalAlignment="Center"
VerticalAlignment="Center" Content="{Binding}" />
</GroupBox>
This will yield a GroupBox
that looks like the following.
这将产生GroupBox
如下所示的结果。
I think that by default in
databinding
, wpf always gets data from theDataContext
property. Seems not indatatemplate
我认为默认情况下
databinding
,wpf 总是从DataContext
属性中获取数据。好像不在datatemplate
Your assumption is correct about DataContext
and it does work in the DataTemplate
as I've demonstrated it's just that in the Header's template the DataContext is the value from the Header Property and not the DataContext itself.
您的假设是正确的DataContext
,它确实适用于DataTemplate
我已经证明的,只是在 Header 的模板中,DataContext 是来自 Header 属性的值,而不是 DataContext 本身。
回答by frankidoze
<GroupBox >
<GroupBox.HeaderTemplate>
<DataTemplate>
<RadioButton Content="myR"
IsChecked="{Binding rIsChecked, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}}" />
</DataTemplate>
</GroupBox.HeaderTemplate>
<GroupBox.Content>
<Grid IsEnabled="{Binding rIsChecked}">
</Grid>
</GroupBox.Content>
</GroupBox>
Just propagate the GroupBox DC to the DataTemplate content...works like a charm...
只需将 GroupBox DC 传播到 DataTemplate 内容......就像一个魅力......
回答by Andre Luus
The lesson learned above is useful in general for DataTemplates, but I actually found out recently there is a better way to change the header of a groupbox:
上面学到的教训通常对 DataTemplates 很有用,但我实际上最近发现有一种更好的方法来更改 groupbox 的标题:
<GroupBox>
<GroupBox.Header>
<CheckBox IsChecked="{Binding Path=mSomeBoolean}"/>
</GroupBox.Header>
</GroupBox>
This way there is no need to define a relative source in the bindings.
这样就不需要在绑定中定义相对源。
Also please note this issuewith GroupBoxes and the header.
另请注意GroupBoxes 和标题的此问题。
回答by stricq
This is what worked for me:
这对我有用:
<HeaderedContentControl Header="{Binding}" Style="{StaticResource TallHeaderedContentStyle}">
<HeaderedContentControl.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=HeaderText"} />
</DataTemplate>
</HeaderedContentControl.HeaderTemplate>