【问题标题】:Cannot get Two Way Template Binding (WPF) to work无法使双向模板绑定 (WPF) 工作
【发布时间】:2022-01-18 05:12:36
【问题描述】:

我需要帮助来了解为什么这不起作用。根据 MSDN,在将模板中控件的属性绑定到实现模板的控件的属性时应该使用 TemplateBinding。

除了模板绑定不是双向的。对于双向,您需要使用绑定,然后将相对源指定为 TemplatedParent。

所以我有以下 XAML: 模板

<ItemContainerTemplate x:Key="colHeaderTemplate">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding}" VerticalAlignment="Center"/>
                <ToggleButton Style="{StaticResource ToggleButtonStyle}" IsChecked="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=TwoWay, Path=(props:VisibilityHelper.IsGroupCollapsed)}"/>
            </StackPanel>
        </ItemContainerTemplate>

这里用的

<dxg:GridColumn x:Name="Total" Header="Total" FieldName="field1" Width="Auto" HorizontalHeaderContentAlignment="Center" props:VisibilityHelper.IsGroupCollapsed="False" HeaderTemplate="{StaticResource colHeaderTemplate}">
                                        <dxg:GridColumn.EditSettings>
                                            <dx:TextEditSettings HorizontalContentAlignment="Center"/>
                                        </dxg:GridColumn.EditSettings>
                                    </dxg:GridColumn>

模板中的切换按钮必须在网格列上设置依赖属性。当模板绑定到父级时,这可以正常工作。控件是嵌套的,

我就是想不通我做错了什么。

MSDN 参考 - http://msdn.microsoft.com/en-us/library/ms742882.aspx

许多关于此的 SO 帖子之一 - In WPF, why doesn't TemplateBinding work where Binding does?

谢谢

【问题讨论】:

  • 我对 WPF 有点生疏了,但如果我没记错的话,ItemContainer(顾名思义)是单元格的容器,而不是单元格小部件。也就是说,如果你想为任何类型的单元格内容可视化器/编辑器安排一个特定的容器。
  • TemplateBinding{RelativeSource TemplatedParent} 只能在 ControlTemplate 内部工作,而您的模板不是这个模板 - 它是 DataTemplate。只要您尝试绑定到列上定义的属性,您似乎需要在绑定中设置 RelativeSource{RelativeSource FindAncestor, AncestorType={x:Type dxg:GridColumn}}
  • ItemContainerTemplate和DataTemplate一样吗,因为我用的是ItemContainerTemplate?无论哪种方式,我都实现了您对@Quercus 的建议,但正如预期的那样,我得到了以下Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='DevExpress.Xpf.Grid.GridColumn', AncestorLevel='1''. BindingExpression:Path=(0); DataItem=null; target element is 'ToggleButton' (Name=''); target property is 'IsChecked' (type 'Nullable1')`,这是我所期望的,因为 FindAncestor 只有在我理解正确的情况下才适用于嵌套控件
  • @dracosveen ItemContainerTemplateDataTemplate 的后代。但是,FindAncestor 应该可以工作-您将模板作为HeaderTemplate 传递给列,这意味着当创建列时,它将使用此模板在标题中创建实际控件,而在运行时ToggleButton 将嵌套控制列的标题以及列本身。

标签: c# wpf templatebinding


【解决方案1】:

是的,我找到了解决方案。首先 DataTemplate 确实有效。作为@Quercus,这一切都在绑定到正确的控件中。

在我的例子中,不是 GridColumn,而是 GridColumnHeader。所以这个

IsChecked="{Binding RelativeSource={RelativeSource AncestorType=dxg:GridColumnHeader}, Path=DataContext.(props:VisibilityHelper.IsGroupCollapsed)}"

完美运行...当绑定到正确的父级时。

正如@Quercus 所说,模板实际上是嵌套的,这就是它起作用的原因。我使用了一个名为 Snoop 的工具,它实际上向您展示了应用程序的可视化树,然后是所选元素的数据上下文。使用这个我解决了这个问题以及我遇到的其他 2 个问题。

我真的希望这可以在每个人都使用 MAUI 或 WinUI 3 之前对某个地方的人有所帮助。

【讨论】:

    猜你喜欢
    • 2011-02-25
    • 1970-01-01
    • 2017-04-01
    • 2014-04-10
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    相关资源
    最近更新 更多