【发布时间】:2010-07-17 14:10:00
【问题描述】:
我有一个用户控件,它有一个网格(您在创建用户控件时自动获得的那个)和其中的一个画布。
<Grid x:Name="LayoutRoot" Background="White">
<Canvas x:Name="SurfaceCanvas">
</Canvas>
</Grid>
在 CS 文件中,我定义了一个“Items”集合。
public ObservableCollection<TestItem> Items {
get { return (ObservableCollection<TestItem>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register("Items", typeof(ObservableCollection<TestItem>),
typeof(TestControl),
new PropertyMetadata(new ObservableCollection<TestItem>()));
TestItem 类声明:
public class TestItem : ContentControl { ... }
通过 XAML 添加项目。
<my:TestControl x:Name="ControlOne" Height="100" Width="100">
<my:TestControl.Items>
<my:TestItem x:Name="ItemOne">One</my:TestItem>
</my:TestControl.Items>
</my:TestControl>
<my:TestControl x:Name="ControlTwo" Height="100" Width="100">
<my:TestControl.Items>
<my:TestItem x:Name="ItemTwo">Two</my:TestItem>
</my:TestControl.Items>
</my:TestControl>
当项目被添加到集合中时,我将它们添加到画布中。
void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
switch(e.Action) {
case NotifyCollectionChangedAction.Add:
foreach(Control item in e.NewItems) {
SurfaceCanvas.Children.Add(item);
}
break;
}
}
现在,问题来了。
如果此控件有一个实例,则一切正常。但是当我定义第二个实例时,我在添加到ControlTwo 的项目上收到InvalidOperationException:“元素已经是另一个元素的子元素”。
当我逐步查看元素被添加到画布时,发生的情况是它创建 ItemOne 并将其添加到 ControlOne,然后创建 ItemTwo 并将其添加到 ControlOne,然后再尝试添加发给ControlTwo。这会导致异常,因为您不能同时将一个元素作为两个控件的父级。
我的猜测是它与每个实例中的画布具有相同名称的事实有关,因此当它解析“SurfaceCanvas”时,它会返回两个实例并按顺序添加到每个实例中。这只是基于观察的猜测。
我做错了什么?
【问题讨论】:
标签: c# wpf silverlight xaml user-controls