【问题标题】:WPF GroupBox HeaderTemplate and DataBindingWPF GroupBox HeaderTemplate 和 DataBinding
【发布时间】:2018-02-20 05:04:35
【问题描述】:

我在 wpf groupbox 中定义了一个 headertemplate 并且数据绑定不起作用。我不明白为什么。

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

【问题讨论】:

    标签: wpf groupbox


    【解决方案1】:

    问题在于HeaderTemplate 用于模板标头,因此在HeaderTemplate 内,您的DataContext 是您绑定或分配给GroupBoxHeader 属性的任何内容。

    认为Header 属性几乎就像控件标题的DataContext。通常DataContext 属性从其父级继承其值,但由于并非每个控件都有Header,除非您设置它,否则标题为空白。

    通过将您的 Header 显式绑定到当前 DataContext Header="{Binding}" 您的示例应该可以按预期工作。为了帮助说明这是如何工作的,我在下面创建了一个简单的示例,显示了HeaderDataContext 如何相互独立地工作,以便为控件的主体或标题提供数据。

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

    这将产生一个GroupBox,如下所示。

    我认为默认情况下在databinding 中,wpf 总是从DataContext 属性中获取数据。似乎不在datatemplate

    您对DataContext 的假设是正确的,并且它在DataTemplate 中确实有效,正如我已经证明的那样,只是在标头的模板中,DataContext 是来自标头属性的值,而不是 DataContext 本身。

    【讨论】:

    • +1,此信息确实有助于标题在组框中的工作方式!
    • 请注意,这些观察结果通常也适用于任何 HeaderedContentControl。
    • 这个答案最重要的一点是,如果要使用 HeaderTemplate,则需要设置 Header="{Binding}"。
    【解决方案2】:

    GroupBox 没有名为“CurrentContract”的成员。最有可能的是,您想从相应的 ViewModel 访问一个名为“CurrentContract”的属性?! ViewModel 是 GroupBox 的 DataContext,因此您必须将 Binding Paths 更改为...

    <Binding Path="DataContext.CurrentContract.Type" Converter="{StaticResource contractTypeConverter}" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}">
    

    【讨论】:

    • 谢谢。我认为默认情况下,在数据绑定中,wpf 总是从 DataContext 属性中获取数据。似乎不在数据模板中。
    • 或者,您可以通过在 GroupBox 声明中执行类似于 Header="{Binding}" 的操作将 DataContext 绑定到 Header。这样,您的 DataTemplate 将按原样工作。有关详细信息,请参阅我的答案。
    【解决方案3】:
        <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>
    

    只需将 GroupBox DC 传播到 DataTemplate 内容...就像一个魅力...

    【讨论】:

    • 我认为这是最简单的。谢谢。
    【解决方案4】:

    上面学到的经验对 DataTemplates 来说是很有用的,但我最近发现有一种更好的方法来更改 groupbox 的标题:

    <GroupBox>
        <GroupBox.Header>
            <CheckBox IsChecked="{Binding Path=mSomeBoolean}"/>
        </GroupBox.Header>
    </GroupBox>
    

    这样就不需要在绑定中定义相对源了。

    另外请注意 this issue 与 GroupBoxes 和标题。

    【讨论】:

    • 直接在 Header 属性上设置可视内容效果很好,但如果您了解 HeaderTemplate 的工作原理,则没有理由避免使用它。请参阅我的答案以获得解释。
    【解决方案5】:

    这对我有用:

    <HeaderedContentControl Header="{Binding}" Style="{StaticResource TallHeaderedContentStyle}">
      <HeaderedContentControl.HeaderTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Path=HeaderText"} />
        </DataTemplate>
      </HeaderedContentControl.HeaderTemplate>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      相关资源
      最近更新 更多