我有這樣的用戶控件:指定的元素已經是另一個元素的邏輯子元素。先斷開它。在用戶控制
[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;
}
}
而且我在這裏使用它:
<p:PanelControl>
<Button />
<Button />
<Button />
</p:PanelControl>
當我開始應用它的作品不錯,但在設計師,我已經強調了XAML和錯誤第一個按鈕「指定的元素已經是另一個元素的邏輯子元素,請先斷開它。」感謝您的幫助,對不起我的糟糕英語。