protectedoverride Size ArrangeOverride(Size arrangeSize) { var width = arrangeSize.Width; var height = arrangeSize.Height;
double left = 0d, top = 0d; for (var y = 0; y int)height / _maxSize; y++) { double yNum = y + 1; yNum = _maxSize * yNum; for (var x = 0; x int)width / _maxSize; x++) { if (_number > InternalChildren.Count - 1) return arrangeSize;
var item = InternalChildren[_number] as FrameworkElement;
if (DoubleUtil.IsNaN(item.ActualWidth) || DoubleUtil.IsZero(item.ActualWidth) || DoubleUtil.IsNaN(item.ActualHeight) || DoubleUtil.IsZero(item.ActualHeight)) ResizeItem(item);
privatestaticlong _tick = DateTime.Now.Ticks; publicstatic Random GetRandom = new Random((int)(_tick & 0xffffffffL) | (int)(_tick >> 32));
publicstaticdoubleNextDouble(double miniDouble, double maxiDouble) { if (GetRandom != null) { return GetRandom.NextDouble() * (maxiDouble - miniDouble) + miniDouble; } else { return0.0d; } } publicstatic Brush RandomBrush() { var R = GetRandom.Next(255); var G = GetRandom.Next(255); var B = GetRandom.Next(255); var color = Color.FromRgb((byte)R, (byte)G, (byte)B); var solidColorBrush = new SolidColorBrush(color); return solidColorBrush; }
3) BubbleControl.cs 代码如下;
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; using WPFDevelopers.Helpers;
namespaceWPFDevelopers.Controls { [TemplatePart(Name = BorderTemplateName, Type = typeof(Border))] [TemplatePart(Name = EllipseTemplateName, Type = typeof(Ellipse))] [TemplatePart(Name = RotateTransformTemplateName, Type = typeof(RotateTransform))] publicclassBubblleControl : Control { privateconststring BorderTemplateName = "PART_Border"; privateconststring EllipseTemplateName = "PART_Ellipse"; privateconststring RotateTransformTemplateName = "PART_EllipseRotateTransform"; privateconststring ListBoxTemplateName = "PART_ListBox";
privatestaticreadonly Type _typeofSelf = typeof(BubblleControl);
private ObservableCollection _items = new ObservableCollection();
publicnewstaticreadonly DependencyProperty EarthBackgroundProperty = DependencyProperty.Register("EarthBackground", typeof(Brush), typeof(BubblleControl), new PropertyMetadata(Brushes.DarkOrchid)); public Brush BorderBackground { get => (Brush)this.GetValue(BorderBackgroundProperty); set => this.SetValue(BorderBackgroundProperty, (object)value); } public Brush EarthBackground { get => (Brush)this.GetValue(EarthBackgroundProperty); set => this.SetValue(EarthBackgroundProperty, (object)value); } #endregion
#region Property
publicstaticreadonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable<string>), typeof(BubblleControl), new PropertyMetadata(null, OnItemsSourcePropertyChanged)); public IEnumerable<string> ItemsSource { get { return (IEnumerable<string>)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } }
privatestaticvoidOnItemsSourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { var ctrl = obj as BubblleControl; var newValue = e.NewValue as IEnumerable<string>;
if (newValue == null) { ctrl._items.Clear(); return; }
foreach (var item in newValue) { ctrl._items.Add(new BubblleItem { Text = item, Bg = ControlsHelper.RandomBrush() }); } }
#endregion
#region Override
publicoverridevoidOnApplyTemplate() { base.OnApplyTemplate(); _border = GetTemplateChild(BorderTemplateName) as Border; _ellipse = GetTemplateChild(EllipseTemplateName) as Ellipse; _rotateTransform = GetTemplateChild(RotateTransformTemplateName) as RotateTransform; Loaded += delegate { var point = _border.TranslatePoint(new Point(_border.ActualWidth / 2, _border.ActualHeight / 2), _ellipse); _rotateTransform.CenterX = point.X - _ellipse.ActualWidth / 2; _rotateTransform.CenterY = point.Y - _ellipse.ActualHeight / 2; }; _listBox = GetTemplateChild(ListBoxTemplateName) as ItemsControl; _listBox.ItemsSource = _items; }