2016-03-18 10 views
2

bu UserControl var:Belirtilen öğe zaten başka bir öğenin mantıksal çocuğu. Önce bağlantısını kesin. Kullanıcı Kontrol

[ContentProperty("Items")] 
[DefaultProperty("Items")] 
public partial class PanelControl : UserControl 
{ 
    public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(PanelControl), new FrameworkPropertyMetadata(Orientation.Horizontal, new PropertyChangedCallback(OnOrientationChanged))); 
    public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection<UIElement>), typeof(PanelControl), new FrameworkPropertyMetadata(new ObservableCollection<UIElement>(), new PropertyChangedCallback(OnItemsChanged))); 
    public static readonly DependencyProperty SizeProperty = DependencyProperty.RegisterAttached("Size", typeof(double), typeof(PanelControl), new FrameworkPropertyMetadata(1.0, new PropertyChangedCallback(OnSizeChanged)), new ValidateValueCallback(IsSizeValid)); 

    public Orientation Orientation 
    { 
     get 
     { 
      return (Orientation)GetValue(OrientationProperty); 
     } 
     set 
     { 
      SetValue(OrientationProperty, value); 
     } 
    } 

    public ObservableCollection<UIElement> Items 
    { 
     get 
     { 
      return (ObservableCollection<UIElement>)GetValue(ItemsProperty); 
     } 
     set 
     { 
      SetValue(ItemsProperty, value); 
     } 
    } 

    public static void SetSize(UIElement element, double size) 
    { 
     element.SetValue(SizeProperty, size); 
    } 
    public static double GetSize(UIElement element) 
    { 
     return (double)element.GetValue(SizeProperty); 
    } 

    private static void OnOrientationChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) 
    { 
     /*MessageBox.Show("orientation");*/ 
     ((PanelControl)dependencyObject).ClearAndBuildGrid(); 
    } 

    private static void OnItemsChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) 
    { 
     /*MessageBox.Show("items");*/ 
     ((PanelControl)dependencyObject).ClearAndBuildGrid(); 
     if(args.OldValue != null) 
      ((ObservableCollection<UIElement>)args.OldValue).CollectionChanged -= ((PanelControl)dependencyObject).OnItemsCollectionChanged; 
     if (args.NewValue != null) 
      ((ObservableCollection<UIElement>)args.NewValue).CollectionChanged += ((PanelControl)dependencyObject).OnItemsCollectionChanged; 

    } 

    private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) 
    { 
     /*MessageBox.Show("collection");*/ 
     ClearAndBuildGrid(); 
    } 

    private static void OnSizeChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) 
    { 
     ((PanelControl)dependencyObject).ClearAndBuildGrid(); 
     /*MessageBox.Show("size");*/ 
    } 
    private static bool IsSizeValid(object value) 
    { 
     return (double)value < 0 ? false : true; 
    } 

    private void ClearAndBuildGrid() 
    { 
     MainGrid.Children.Clear(); 
     MainGrid.RowDefinitions.Clear(); 
     MainGrid.ColumnDefinitions.Clear(); 
     /*MessageBox.Show(MainGrid.Children.Count.ToString());*/ 
     for (int i = 0; i < Items.Count; i++) 
     { 
      if (Orientation == Orientation.Horizontal) 
      { 
       MainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = SizeToGridLength(GetSize(Items[i])) }); 
       Grid.SetColumn(Items[i], i * 2); 
       if (i != Items.Count - 1) 
       { 
        MainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(5) }); 
        GridSplitter splitter = new GridSplitter() { ResizeDirection = GridResizeDirection.Columns, HorizontalAlignment = HorizontalAlignment.Stretch }; 
        Grid.SetColumn(splitter, i * 2 + 1); 
        MainGrid.Children.Add(splitter); 
       } 
      } 
      else 
      { 
       MainGrid.RowDefinitions.Add(new RowDefinition() { Height = SizeToGridLength(GetSize(Items[i])) }); 
       Grid.SetRow(Items[i], i * 2); 
       if (i != Items.Count - 1) 
       { 
        MainGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(5) }); 
        GridSplitter splitter = new GridSplitter() { ResizeDirection = GridResizeDirection.Rows, VerticalAlignment = VerticalAlignment.Stretch }; 
        Grid.SetRow(splitter, i * 2 + 1); 
        MainGrid.Children.Add(splitter); 
       } 
      } 
      MainGrid.Children.Add(Items[i]); 
     } 
    } 

    private GridLength SizeToGridLength(double size) 
    { 
     return new GridLength(size, GridUnitType.Star); 
    } 

    public PanelControl() 
    { 
     InitializeComponent(); 
     Items.CollectionChanged += OnItemsCollectionChanged; 
    } 
} 

Ve ben burada kullanmak:

<p:PanelControl> 
    <Button /> 
    <Button /> 
    <Button /> 
</p:PanelControl> 

ben iyi çalışır uygulamayı başlatmak, ama tasarımcı içinde xaml yanılma ilk düğmeyi vurgulamışlardır zaman "Belirtilen öğe zaten başka bir öğenin mantıksal çocuğu. Önce bağlantısını kesin." Yardımınız için teşekkürler, kötü ingilizcem için özür dilerim.

cevap

2

Tasarımcıyla olan bitenden emin değil, ancak bu 'düzeltmek' olacak.

değiştirme hattı:

MainGrid.Children.Add(Items[i]); 

için: JH gelen kodu kullanarak

var parent = VisualTreeHelper.GetParent(Items[i]) as Grid; 
if (parent != null) 
    parent.Children.Remove(Items[i]); 
MainGrid.Children.Add(Items[i]); 
0

, ben senin işlevin üstüne o kadar hareket edeceğini böylece ızgara zaman devlet Onu temizler, "temizlenir" ve tüm çocuklar Görsel Ağacı ile bağlantısı kesildi.

private void ClearAndBuildGrid() 
{ 
    foreach (var item in Items) 
    { 
     var parent = System.Windows.Media.VisualTreeHelper.GetParent(item) as Grid; 
     if (parent != null) 
      parent.Children.Remove(item); 
    } 
    MainGrid.Children.Clear(); 

Bir stil/niyeti/tercihi şey olacağını ve net olmak gerekirse, cevap J. H. verir tamamen geçerlidir.

for yerine foreach kullanmayı ve dizi abonelikleriyle uğraşmak zorunda kalmayı düşünün.

İlgili konular