2012-06-13 84 views
1

我使用this站點的示例來創建MultiColumnStackPanel。WP7自定義MultiColumnStackPanel項目子項已具有父項

然而有一個問題。一旦頁面被加載,堆疊面板看起來很好,就像這個例子一樣。但是,當我導航到下一頁,然後返回到上一頁時,我收到一個異常:

InvalidOperationException
隨着以下消息:
Element is already the child of another element.

所以我認爲包含在原來的自定義堆棧面板中的項目被添加到一個新的自定義堆棧面板。但爲什麼MultiColumnStackPanel正在'刷新'並且是否仍然存在MultiColumnStackPanel.Items

是否有其他人對此問題有解釋/解決方案?

在此先感謝

MultiColumnStackPanel類:

public class MultiColumnStackPanel : StackPanel 
{ 
    public int NumberOfColumns { get; set; } 

    public static readonly DependencyProperty ItemsProperty = 
      DependencyProperty.Register("Items", 
      typeof(Collection<UIElement>), 
      typeof(MultiColumnStackPanel), 
      new PropertyMetadata(new Collection<UIElement>())); 

    public Collection<UIElement> Items 
    { 
     get { return (Collection<UIElement>)GetValue(ItemsProperty); } 
    } 

    public MultiColumnStackPanel() 
    { 
     Loaded += (s, e) => 
     { 
      LoadItems(); 
     }; 
    } 

    void LoadItems() 
    { 
     Children.Clear(); 

     if (Items != null) 
     { 
      StackPanel sp = CreateNewStackPanel(); 
      foreach (UIElement item in Items) 
      { 
       sp.Children.Add(item); 
       if (sp.Children.Count == NumberOfColumns) 
       { 
        Children.Add(sp); 
        sp = CreateNewStackPanel(); 
       } 
      } 

      if (sp.Children.Count > 0) 
       Children.Add(sp); 
     } 
    } 

    private StackPanel CreateNewStackPanel() 
    { 
     Orientation oppositeOrientation; 

     if(this.Orientation.Equals(Orientation.Vertical)) 
      oppositeOrientation = Orientation.Horizontal; 
     else 
      oppositeOrientation = Orientation.Vertical; 

     return new StackPanel() { Orientation = oppositeOrientation }; 
    } 
} 

XAML例如:

<model:MultiColumnStackPanel x:Name="customStackPanel" Orientation="Horizontal" NumberOfColumns="2"> 
    <model:MultiColumnStackPanel.Items> 
     <Rectangle Height="80" Width="80" Margin="10" Fill="Green" /> 
     <Rectangle Height="80" Width="80" Margin="10" Fill="Green" /> 
     <Rectangle Height="80" Width="80" Margin="10" Fill="Green" /> 
     <Rectangle Height="80" Width="80" Margin="10" Fill="Green" /> 
    </model:MultiColumnStackPanel.Items> 
</model:MultiColumnStackPanel> 
+0

仔細調試應用程序的步驟步。當返回時,Loaded事件再次被提出,我想那會導致YOu的問題。 – nkchandra

+0

感謝提示 – akalucas

回答

0

我想通了,我想我會分享我的發現。

在MultiColumnStackPanel的構造函數中,函數LoadItems()綁定到StackPanel的Loaded事件。

當導航到下一個頁面然後導航時,MultiColumnStackPanel不會像我之前想的那樣再次創建。 MultiColumnStackPanel的Loaded事件再次被簡單地觸發。

public MultiColumnStackPanel() 
{ 
    Loaded += (s, e) => 
    { 
     LoadItems(); 
    }; 
} 

然後我看到每個LoadItems()函數被調用一次清除對象的子女。如果孩子已經在場了,那麼除去這個訣竅就沒有必要再次從Items列表中添加它們。

void LoadItems() 
{ 
    // Children.Clear(); 

    if (Items != null && (Children == null || Children.Count == 0)) 
    { 
     StackPanel sp = CreateNewStackPanel(); 
     foreach (UIElement item in Items) 
     { 
      sp.Children.Add(item); 
      if (sp.Children.Count == NumberOfColumns) 
      { 
       Children.Add(sp); 
       sp = CreateNewStackPanel(); 
      } 
     } 
     if (sp.Children.Count > 0) 
      Children.Add(sp); 
    } 
} 

有時候你需要一點自我反省=)

編輯

還要說明一點,ItemsProperty不應該是靜態

public static readonly DependencyProperty ItemsProperty = // <-- remove static 
    DependencyProperty.Register("Items", 
    typeof(Collection<UIElement>), 
    typeof(MultiColumnStackPanel), 
    new PropertyMetadata(new Collection<UIElement>())); 
+0

我只是想知道,你解決了這個問題沒有我的上述評論的幫助? – nkchandra

+0

部分,感謝您的評論,我進一步探討了Loaded事件;) – akalucas

相關問題