2010-07-17 46 views
3

我有一個用戶控件,它具有一個網格(您在創建用戶控件時自動獲取的網格)和一個畫布。用畫布控制用戶的多個實例在Silverlight中導致異常

<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,並試圖將其添加到ControlTwo之前將其添加到ControlOne。這會導致異常,因爲您無法一次將父元素設爲父元素。

我的猜測是它與每個實例中的畫布具有相同名稱的事實有關,所以當它解析「SurfaceCanvas」時,它將返回兩個實例並按順序添加到每個實例中。這只是基於觀察的猜測。

我在做什麼錯?

回答

3

花了一分鐘,但是這是非常棘手:

你必須爲你的DependencyProperty的默認值。默認值只爲DependencyProperty創建一次,然後分配給TestControl的兩個實例。這樣,當你向TestControl.Items添加一些東西時,你可以將它添加到公共的ObservbleCollection中,該公共ObservbleCollection現在有兩個CollectionChanged事件委託,每個委託都將新的項目添加到它們各自的Canvas中。

刪除ItemsProperty的默認值。要麼在構造函數中創建一個ObservbleCollection,要麼xaml解釋器將爲每個TestControl創建一個。

規則:僅對值類型使用DependencyProperty的默認值,而不使用引用類型。

+0

謝謝你一步一步推動我的教育。 – redman 2010-07-17 14:58:24

+0

+1,這是所有具有引用類型的DependencyProperties的經典陷阱。不過,我會稍微放鬆一下規則,「僅對值類型使用默認值__或___以引用不可變對象」。一個「不可變」的好例子就是一個「字符串」。 – AnthonyWJones 2010-07-17 18:29:20

相關問題