using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace RazorEngineTest { [ContentProperty("Children")] [TemplatePart(Name = "PART_ChildrenContainer", Type = typeof(ItemsControl))] public class MyGrid : Control { [AllowNull] private ItemsControl PART_ChildrenContainer; [AllowNull] private Grid ChildrenContainer; static MyGrid() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyGrid), new FrameworkPropertyMetadata(typeof(MyGrid))); } public MyGrid() { this.Children = new UICollection(); this.RowDefinitions = new RowDefinitions(); this.ColDefinitions = new ColDefinitions(); } public override void OnApplyTemplate() { base.OnApplyTemplate(); this.PART_ChildrenContainer = this.GetTemplateChild("PART_ChildrenContainer") as ItemsControl; if (this.PART_ChildrenContainer != null) this.PART_ChildrenContainer.Loaded += PART_ChildrenContainer_Loaded; else throw new ArgumentNullException($"「{nameof(MyGrid)}」模版必须定义名称为「PART_ChildrenContainer」的「ItemsControl」类型子元素容器..."); } private void PART_ChildrenContainer_Loaded(object sender, RoutedEventArgs e) { this.ChildrenContainer = this.PART_ChildrenContainer.FindVisualChild("ChildrenContainer"); if (this.ChildrenContainer != null) { this.ChildrenContainer.ShowGridLines = DesignerProperties.GetIsInDesignMode(this); this.ChildrenContainer.RowDefinitions.Clear(); foreach (var row in this.RowDefinitions) this.ChildrenContainer.RowDefinitions.Add(row); this.ChildrenContainer.ColumnDefinitions.Clear(); foreach (var col in this.ColDefinitions) this.ChildrenContainer.ColumnDefinitions.Add(col); } } /// /// 子元素集合 /// public UICollection Children { get { return (UICollection)GetValue(ChildrenProperty); } set { SetValue(ChildrenProperty, value); } } public static readonly DependencyProperty ChildrenProperty = DependencyProperty.Register("Children", typeof(UICollection), typeof(MyGrid), new PropertyMetadata(null, (d, e) => (d as MyGrid)?.Children_PropertyChangedCallback(e))); /// /// 处理「MyGrid.Children」属性变更 /// protected virtual void Children_PropertyChangedCallback(DependencyPropertyChangedEventArgs e) { if (e.OldValue is UICollection oldUIColl) oldUIColl.CollectionChanged -= UICollection_CollectionChanged; if (e.NewValue is UICollection newUIColl) newUIColl.CollectionChanged += UICollection_CollectionChanged; } protected virtual void UICollection_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { //TODO:这里可以处理逻辑树的父子级关系 } /// /// 行定义 /// public RowDefinitions RowDefinitions { get { return (RowDefinitions)GetValue(RowDefinitionsProperty); } protected internal set { SetValue(RowDefinitionsPropertyKey, value); } } public static readonly DependencyPropertyKey RowDefinitionsPropertyKey = DependencyProperty.RegisterReadOnly("RowDefinitions", typeof(RowDefinitions), typeof(MyGrid), new PropertyMetadata(null, (d, e) => (d as MyGrid)?.RowDefinitions_PropertyChangedCallback(e))); public static readonly DependencyProperty RowDefinitionsProperty = RowDefinitionsPropertyKey.DependencyProperty; /// /// 处理「MyGrid.RowDefinitions」属性变更 /// protected virtual void RowDefinitions_PropertyChangedCallback(DependencyPropertyChangedEventArgs e) { if (e.OldValue is RowDefinitions oldRows) oldRows.CollectionChanged -= Rows_CollectionChanged; if (e.NewValue is RowDefinitions newRows) newRows.CollectionChanged += Rows_CollectionChanged; } private void Rows_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (this.ChildrenContainer != null) { this.ChildrenContainer.RowDefinitions.Clear(); foreach (var row in this.RowDefinitions) this.ChildrenContainer.RowDefinitions.Add(row); } } /// /// 列定义 /// public ColDefinitions ColDefinitions { get { return (ColDefinitions)GetValue(ColDefinitionsProperty); } protected internal set { SetValue(ColDefinitionsPropertyKey, value); } } public static readonly DependencyPropertyKey ColDefinitionsPropertyKey = DependencyProperty.RegisterReadOnly("ColDefinitions", typeof(ColDefinitions), typeof(MyGrid), new PropertyMetadata(null, (d, e) => (d as MyGrid)?.ColDefinitions_PropertyChangedCallback(e))); public static readonly DependencyProperty ColDefinitionsProperty = ColDefinitionsPropertyKey.DependencyProperty; /// /// 处理「MyGrid.ColDefinitions」属性变更 /// protected virtual void ColDefinitions_PropertyChangedCallback(DependencyPropertyChangedEventArgs e) { if (e.OldValue is ColDefinitions oldCols) oldCols.CollectionChanged -= Cols_CollectionChanged; if (e.NewValue is ColDefinitions newCols) newCols.CollectionChanged += Cols_CollectionChanged; } private void Cols_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (this.ChildrenContainer != null) { this.ChildrenContainer.ColumnDefinitions.Clear(); foreach (var col in this.ColDefinitions) this.ChildrenContainer.ColumnDefinitions.Add(col); } } } [DefaultMember("Items")] public class RowDefinitions : ObservableCollection { public RowDefinitions() { } } [DefaultMember("Items")] public class ColDefinitions : ObservableCollection { public ColDefinitions() { } } }