错误"指定的元素已经是另一个元素的逻辑子元素"?

Rac*_*hel 13 wpf xaml mvvm

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

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

ButtonClick命令:

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

这会触发Style上的PropertyChange事件

public Style EditPanelStyle
{
    get { return _editPanelStyle; }
    set
    {
        if (_editPanelStyle != value)
        {
            _editPanelStyle = value;
            OnPropertyChanged("EditPanelStyle");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这会触发ViewModelBase中的OnPropertyChanged事件

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

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

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

编辑

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

与失败和成功的主要区别在于Style位于不同的位置.

编辑#2 失败的样式 - LookupDialog是一个自定义的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>
Run Code Online (Sandbox Code Playgroud)

工作方式:

<!-- 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>
Run Code Online (Sandbox Code Playgroud)

Rac*_*hel 20

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

无论如何+1来Davy帮助我完成这个.


Dav*_*vy8 8

确保您正在创建新的选项卡对象,而不是第二次尝试将相同的选项卡插入选项卡控件.一个控件只能有一个父控件,看起来问题是你试图将一个选项卡插入到两个不同的容器中,或者更可能是两个相同的选项卡控件.