定义 DataGridTemplateColumn.Header 导致“指定元素已经是另一个元素的逻辑子元素。首先断开它”异常

Posted

技术标签:

【中文标题】定义 DataGridTemplateColumn.Header 导致“指定元素已经是另一个元素的逻辑子元素。首先断开它”异常【英文标题】:Defining DataGridTemplateColumn.Header is causing "Specified element is already the logical child of another element. Disconnect it first" exception 【发布时间】:2019-05-01 21:22:24 【问题描述】:

我有一个 MVVM WPF 应用程序。此应用程序有两个数据网格。

其中一个具有 DataGridTemplateColumn 等。当我重新加载 UI 时,此 DataGridTemplateColumn 导致异常。在错误的屏幕截图下方(注意:如果我删除了这个 DataGridTemplateColumn 则一切正常,不会引发异常):

它是西班牙语的。英文是:“指定元素已经是另一个元素的逻辑子元素。先断开它”

我检测到罪魁祸首是当我通过这样做定义 DataGridTemplateColumn 的标题时:

<dg:DataGridTemplateColumn.Header>
    <StackPanel  Orientation="Horizontal" >
        <Image RenderOptions.BitmapScalingMode="NearestNeighbor"
               Width="32" Height="32" 
               Source="/My.Utilities.Resources;component/Images/MyIcon.png"/>
        <TextBlock Text="Show PDF" VerticalAlignment="Center"/>
    </StackPanel>
</dg:DataGridTemplateColumn.Header>

如果我删除上面的 DataGridTemplateColumn.Header 部分,那么它可以工作并且不会引发异常。为什么?如何解决?

通过将项目列表分配给 ItemsSource 数据网格属性来初始化 DataGrid。

DataGrid 资源是:

<!-- DataGrid Resources -->
<dg:DataGrid.Resources>
    <proxy:BindingProxy x:Key="myProxy" Data="Binding" />                       
</dg:DataGrid.Resources>

而代理类是:

public class BindingProxy : Freezable

    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    
        return new BindingProxy();
    

    #endregion

    public object Data
    
        get  return (object)GetValue(DataProperty); 
        set  SetValue(DataProperty, value); 
    

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));

DataGridTemplateColumn 如下所示。基本上它包含一个链接,当单击该链接时,它会调用带有参数的命令。该参数为同一datagrid的另一列包含的pdf文件名:

<dg:DataGridTemplateColumn MinWidth="100" Width="auto">
    <dg:DataGridTemplateColumn.Header>
        <StackPanel  Orientation="Horizontal" >
            <Image RenderOptions.BitmapScalingMode="NearestNeighbor"
                   Width="32" Height="32" 
                   Source="/My.Utilities.Resources;component/Images/MyIcon.png"/>
            <TextBlock Text="Show PDF" VerticalAlignment="Center"/>
        </StackPanel>
    </dg:DataGridTemplateColumn.Header>
    <dg:DataGridTemplateColumn.CellTemplate>                               
        <DataTemplate>
                <TextBlock VerticalAlignment="Center">  

                    <Hyperlink Command="Binding Path=Data.ShowPdf, Source=StaticResource myProxy" 
                               CommandParameter="Binding Path=FileName" >
                        Show PDF
                    </Hyperlink>                

                </TextBlock>
        </DataTemplate>
    </dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>

【问题讨论】:

【参考方案1】:

我已经解决了。我通过更改更改了定义 DataGridTemplateColumn 标头的方式:

<dg:DataGridTemplateColumn.Header>
    <StackPanel  Orientation="Horizontal" >
        <Image RenderOptions.BitmapScalingMode="NearestNeighbor"
               Width="32" Height="32" 
               Source="/My.Utilities.Resources;component/Images/MyIcon.png"/>
        <TextBlock Text="Show PDF" VerticalAlignment="Center"/>
    </StackPanel>
</dg:DataGridTemplateColumn.Header>

这个:

<dg:DataGridTemplateColumn.HeaderStyle>
    <Style TargetType="dg:DataGridColumnHeader">
      <Setter Property="ContentTemplate">
        <Setter.Value>
             <DataTemplate>
                 <StackPanel  Orientation="Horizontal" >
                      <Image RenderOptions.BitmapScalingMode="NearestNeighbor"
                           Width="32" Height="32"                              Source="/My.Utilities.Resources;component/Images/MyIcon.png"/>
                      <TextBlock Text="Show PDF" VerticalAlignment="Center"/>
                 </StackPanel>
             </DataTemplate>
        </Setter.Value>
      </Setter>
     </Style>
</dg:DataGridTemplateColumn.HeaderStyle>

现在它就像一个魅力!

我找到了Frydex提出的解决方案here。

【讨论】:

以上是关于定义 DataGridTemplateColumn.Header 导致“指定元素已经是另一个元素的逻辑子元素。首先断开它”异常的主要内容,如果未能解决你的问题,请参考以下文章

定义 DataGridTemplateColumn.Header 导致“指定元素已经是另一个元素的逻辑子元素。首先断开它”异常

ComboBox不会在DataGridTemplateColumn中显示绑定数据

如何在 DataGridTemplateColumn 内的控件上双向绑定属性?

DataGridTemplateColumn 上边距/填充

如何在代码中从 WPF 数据网格列标题 (DataGridTemplateColumn) 获取工具提示?

DataGrid DataGridTemplateColumn