adminSoftDK
adminSoftDK

Reputation: 2092

Why do I get an exception when using custom control in a listbox datatemplate

Basically, I created very simple custom control, which derives from a popup. I want to use that popup inside a listbox datatemplate, so each listbox item will have it. But I get this error message "Specified element is already the logical child of another element. Disconnect it first", I know what this message means, I've had to deal with this in the past. But in this specific scenario I don't understand why I get it in the first place.

public class MyPopup : Popup
{
    static MyPopup()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyPopup), new FrameworkPropertyMetadata(typeof(MyPopup)));
    }
}

The style for it (which is in Generic file)

<Style x:Key="MyPopupStyle" TargetType="{x:Type local:MyPopup}">
    <Setter Property="Placement" Value="MousePoint" />
    <Setter Property="Child">
        <Setter.Value>
            <Border
                Width="100"
                Height="100"
                Background="HotPink" />
        </Setter.Value>
    </Setter>
    <Setter Property="IsOpen" Value="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.IsMouseOver, Mode=OneWay}" />
</Style>

MainWindow

<Window.Resources>
    <DataTemplate x:Key="Foo">
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock x:Name="TextBlock" Text="Hover over" />
            <wpfApp1:MyPopup PlacementTarget="{Binding ElementName=TextBlock}" />
        </StackPanel>
    </DataTemplate>
 </Window.Resources>
 <ListBox ItemTemplate="{StaticResource Foo}" ItemsSource="{Binding MyList}" />

Code behind

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        MyList = new List<string>{"Dan","John","Test"};
        DataContext = this;
    }
    public List<string> MyList { get; }
}

If I change this custom control to derive from control and put the Popup inside its control template then it works just fine, but I lose properties that I want to access from this popup when consuming this view. I know that I could create dependency properties, to get around it, but ideally I'd like to know what happens here. Thank you.

Upvotes: 0

Views: 47

Answers (1)

SLaks
SLaks

Reputation: 887453

Your Style sets a single instance of Border as the child for all MyPopups.

WPF controls can only have a single parent; that cannot work.

Instead, you need to use a ControlTemplate or DataTemplate, which will make a separate copy of their contents for each control instance.

Upvotes: 2

Related Questions