代码之家  ›  专栏  ›  技术社区  ›  Rachel

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

  •  13
  • Rachel  · 技术社区  · 14 年前

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

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

    按钮单击命令:

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

    这将在样式上触发PropertyChange事件

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

    它会触发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);
        }
    }
    

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

    编辑

    TabItem包含一个画布和一组可以添加/删除/移动的面板。每个面板都有自己的资源目录。从面板中,我可以将PopupStyle设置得很好,它可以毫无问题地应用。面板中使用的样式也在panelResourceDictionary中定义。

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

    编辑2 失败的样式-LookupDialog是自定义WPF用户控件

    <!-- 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>
    
    3 回复  |  直到 13 年前
        1
  •  20
  •   Rachel    14 年前

    我的问题是我正在设置 Content 以我的风格,和 内容 不能有多个逻辑父级。我需要把它移到 Template 相反。因为我不想丢失基本样式,所以我在 ContentTemplate HeaderedContentControl的属性(在我的代码中为DragGablePanel)。

    +不管怎样,我都要感谢戴维帮助我度过难关。

        2
  •  8
  •   Davy8    14 年前

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

        3
  •  -1
  •   Vasyl Boroviak    13 年前

    不阅读以上所有内容,简短的回答是:你需要改变 Content Template (在XAML中,无论是样式还是直接声明 ContentControl )