错误“指定的元素已经是另一个元素的逻辑子元素"? [英] Error "Specified element is already the logical child of another element"?

查看:39
本文介绍了错误“指定的元素已经是另一个元素的逻辑子元素"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 TabControl,每个 Tab 可以包含相同的 UI,但具有不同的数据.在任何选项卡中,用户都可以单击按钮并弹出一个弹出窗口.这为 ViewModel 设置了一个 Style 属性,告诉它用于弹出 UI 的样式.Style 绑定到附加到自定义 PopupUserControl 的自定义 DependecyProperty.我的问题是,当在另一个选项卡中打开弹出窗口的第二个副本时,我收到以下错误(无论应用什么样式):

I have a TabControl and each Tab can contain the same UI but with different data. In any tab the user can click on a button and bring up a popup. This sets a Style property to the ViewModel telling it what style to use for the popup UI. The Style gets bound to a custom DependecyProperty that is attached to a custom PopupUserControl. My problem is that when the a 2nd copy of the popup gets opened in another tab, I get the following error (regardless of what Style is applied):

指定的元素已经是另一个元素的逻辑子元素.先断开连接.

Specified element is already the logical child of another element. Disconnect it first.

ButtonClick 命令:

ButtonClick command:

MyViewModel vm = ((Button)sender).DataContext as MyViewModel;
if (vm != null)
{
    Style popupStyle = (Style)Application.Current.FindResource("SomePopupStyle");
    vm.EditPanelStyle= popupStyle ;
}

这会触发 Style 上的 PropertyChange 事件

This triggers a PropertyChange event on the Style

public Style EditPanelStyle
{
    get { return _editPanelStyle; }
    set
    {
        if (_editPanelStyle != value)
        {
            _editPanelStyle = value;
            OnPropertyChanged("EditPanelStyle");
        }
    }
}

触发 ViewModelBase 中的 OnPropertyChanged 事件

Which triggers the OnPropertyChanged event in the ViewModelBase

protected virtual void OnPropertyChanged(string propertyName)
{
    this.VerifyPropertyName(propertyName);

    PropertyChangedEventHandler handler = this.PropertyChanged;
    if (handler != null)
    {
        var e = new PropertyChangedEventArgs(propertyName);
        handler(this, e);
    }
}

错误发生在 ViewModelBase 中的 handler(this, e);

The error occurs at line handler(this, e); in the ViewModelBase

编辑

TabItem 包含一个 Canvas 和一堆可以添加/删除/移动/等的面板.每个面板都有自己的资源目录.在 Panel 中,我可以很好地设置 PopupStyle,并且可以毫无问题地应用它.面板中使用的样式也在 PanelResourceDictionary 中定义.

The TabItem contains a Canvas and a bunch of panels that can be added/removed/moved/etc. Each Panel has its own resource directory. From within the Panel I can set the PopupStyle just fine and it gets applied without a problem. The Style used within the panels is also defined in the PanelResourceDictionary.

失败者和成功者的主要区别在于样式位于不同的位置.

The main difference with the one that is failing and the ones succeeding is the Style is located in different locations.

编辑 #2失败的样式 - LookupDialog 是一个自定义的 WPF UserControl

EDIT #2 Style that is failing - LookupDialog is a custom WPF UserControl

<!-- Popup Style for LookupDialog -->
<Style x:Key="LookupDialogBaseStyle" TargetType="{x:Type localControls:DraggablePanel}" BasedOn="{StaticResource GenericPopupStyle}">
    <Setter Property="Canvas.Left" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type localControls:PopupPanel}}, 
        Path=ActualWidth, Converter={StaticResource PercentToDoubleConverter}, ConverterParameter=.25}" />
    <Setter Property="Canvas.Top" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type localControls:PopupPanel}}, 
        Path=ActualHeight, Converter={StaticResource PercentToDoubleConverter}, ConverterParameter=.3}" />
    <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type localControls:PopupPanel}}, 
        Path=ActualWidth, Converter={StaticResource PercentToDoubleConverter}, ConverterParameter=.5}" />
    <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type localControls:PopupPanel}}, 
        Path=ActualHeight, Converter={StaticResource PercentToDoubleConverter}, ConverterParameter=.4}" />

    <!--<Setter Property="localControls:PopupPanel.PopupEnterKeyCommand" Value="{Binding Path=SaveCommand}" />-->
    <Setter Property="localControls:PopupPanel.PopupEscapeKeyCommand" Value="{Binding Path=CancelCommand}" />

    <Setter Property="Header" Value="{Binding Path=Header}" />
    <Setter Property="localControls:PopupPanel.BackgroundOpacity" Value="0" />

    <Setter Property="Content">
        <Setter.Value>
            <localControls:LookupDialog 
                DataContext="{Binding}"
                BorderBrush="{StaticResource DarkColor}" />
        </Setter.Value>
    </Setter>
</Style>

<!-- Base Style for a Popup (DraggablePanel) -->
<Style x:Key="GenericPopupStyle" TargetType="{x:Type localControls:DraggablePanel}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type localControls:DraggablePanel}">
                <Border Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">
                    <DockPanel>
                        <!-- Header -->
                        <Border 
                            DockPanel.Dock="Top"
                            MinHeight="20"
                            Background="{DynamicResource TabItem_BackgroundBrush_Unselected}"
                            BorderBrush="{StaticResource DarkColor}"
                            BorderThickness="1"
                            CornerRadius="5,5,0,0"
                            Padding="2,3,2,2"
                            SnapsToDevicePixels="True"
                            >

                            <ContentPresenter x:Name="PART_DraggablePanelHeader" ContentSource="Header" />
                        </Border>

                        <!-- Content -->
                        <Border Background="{StaticResource DefaultBackground}" 
                                BorderBrush="{StaticResource DarkColor}" 
                                BorderThickness="1,0,1,1"
                                SnapsToDevicePixels="True">
                            <ContentPresenter ContentSource="Content" />
                        </Border>
                    </DockPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

有效的风格:

<!-- Example Popup Style for a Panel -->
<Style x:Key="AgentDesktop_NotesPanelPopupStyle" TargetType="{x:Type ContentControl}">
    <Setter Property="Canvas.Left" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type localControls:PopupPanel}}, 
        Path=ActualWidth, Converter={StaticResource PercentToDoubleConverter}, ConverterParameter=.2}" />
    <Setter Property="Canvas.Top" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type localControls:PopupPanel}}, 
        Path=ActualHeight, Converter={StaticResource PercentToDoubleConverter}, ConverterParameter=.32}" />
    <Setter Property="Width" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type localControls:PopupPanel}}, 
        Path=ActualWidth, Converter={StaticResource PercentToDoubleConverter}, ConverterParameter=.6}" />
    <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type localControls:PopupPanel}}, 
        Path=ActualHeight, Converter={StaticResource PercentToDoubleConverter}, ConverterParameter=.36}" />

    <Setter Property="localControls:PopupPanel.PopupEnterKeyCommand" Value="{Binding Path=SaveCommand}" />
    <Setter Property="localControls:PopupPanel.PopupEscapeKeyCommand" Value="{Binding Path=HidePopupCommand}" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <!-- Control Template removed to make this easier to read, but it's created from standard WPF controls with nothing special -->
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

推荐答案

我的问题是我在样式中设置了 Content,而 Content 不能有多个逻辑父.我需要将它移到 Template 代替.由于我不想丢失基本样式,因此我在 HeaderedContentControl(我的代码中的 DraggablePanel)的 ContentTemplate 属性中设置了内容.

My problem was I was setting the Content in my Style, and Content cannot have more then one logical parent. I needed to move that to a Template instead. Since I didn't want to lose the base style, I set the content in the ContentTemplate property of the HeaderedContentControl (DraggablePanel in my code).

无论如何都要为戴维 +1 帮助我解决这个问题.

+1 to Davy anyways for helping me walk through this.

这篇关于错误“指定的元素已经是另一个元素的逻辑子元素"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆