gpt4 book ai didi

wpf - 错误 "Specified element is already the logical child of another element"?

转载 作者:行者123 更新时间:2023-12-03 23:20:23 26 4
gpt4 key购买 nike

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

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



按钮点击命令:
MyViewModel vm = ((Button)sender).DataContext as MyViewModel;
if (vm != null)
{
Style popupStyle = (Style)Application.Current.FindResource("SomePopupStyle");
vm.EditPanelStyle= popupStyle ;
}

这会触发 Style 上的 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 包含一个 Canvas 和一堆可以添加/删除/移动/等的面板。每个 Panel 都有自己的资源目录。在面板中,我可以很好地设置 PopupStyle,它可以毫无问题地应用。面板中使用的样式也在 PanelResourceDictionary 中定义。

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

编辑#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>

有效的风格:
<!-- 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反而。由于不想丢失基础样式,所以将内容设置在ContentTemplate HeaderedContentControl 的属性(我的代码中的 DraggablePanel)。

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

关于wpf - 错误 "Specified element is already the logical child of another element"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4024788/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com