У меня есть пользовательский элемент управления, в котором есть сетка (та, которую вы получаете автоматически при создании пользовательского элемента управления) и холст внутри нее.
<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;
}
}
Теперь проблема.
Если есть один экземпляр этого контроля, все хорошо. Но когда я определяю второй экземпляр, я получаю InvalidOperationException
: «Элемент уже является потомком другого элемента» для элемента, добавленного к ControlTwo
.
Когда я перехожу и наблюдаю, как элементы добавляются на холст, происходит следующее: он создает ItemOne
и добавляет его к ControlOne
, затем создает ItemTwo
и добавляет его к ControlOne
, прежде чем пытаться добавить это к ControlTwo
. Это приводит к исключению, потому что вы не можете иметь элемент, связанный с двумя элементами управления одновременно.
Я предполагаю, что это как-то связано с тем, что холст в каждом экземпляре имеет одно и то же имя, поэтому, когда он разрешает "SurfaceCanvas", он возвращает два экземпляра назад и добавляет к каждому по порядку. Это всего лишь предположение, основанное на наблюдении.
Что я делаю не так?