为什么在列表框datatemplate

时间:2017-11-22 16:46:04

标签: c# wpf xaml custom-controls

基本上,我创建了非常简单的自定义控件,它源自弹出窗口。我想在列表框datatemplate中使用该弹出窗口,因此每个列表框项都将拥有它。但我收到此错误消息 “指定的元素已经是另一个元素的逻辑子元素。首先断开它”,我知道这个消息意味着什么,我过去必须处理这个问题。但在这个具体的情况下,我不明白为什么我首先得到它。

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

它的样式(在通用文件中)

<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}" />

背后的代码

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

如果我将此自定义控件更改为从控件派生并将Popup放入其控件模板中,那么它可以正常工作,但是在使用此视图时,我会丢失我想要从此弹出窗口访问的属性。我知道我可以创建依赖属性,绕过它,但理想情况下我想知道这里发生了什么。谢谢。

1 个答案:

答案 0 :(得分:2)

您的StyleBorder的单个实例设置为所有MyPopup的子项。

WPF控件只能有一个父级;那是行不通的。

相反,您需要使用ControlTemplate或DataTemplate,它将为每个控件实例单独创建其内容的副本。