using OpenTap; using OpenTap.Addin.Annotation; using Panuon.WPF.UI; using System.ComponentModel; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Xml.Serialization; using UILib.DpUtil; namespace OpenTapEditor.Provider { public class TabControlProvider { private static ITypeData resourceTypeData = TypeData.FromType(typeof(IResource)); /// /// 获取需要渲染的属性 /// /// /// public static Dictionary GetRenderProperty(object obj) { var res = new Dictionary(); var properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var property in properties) { if (property.GetCustomAttribute() != null) { res[property.Name] = property; } } return res; } /// /// 获取需要渲染的方法 /// /// /// public static Dictionary GetRenderMethods(object obj) { var res = new Dictionary(); var methods = obj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (var method in methods) { if (method.GetCustomAttribute() != null) { res[method.Name] = method; } } return res; } public static bool FilterMember(IMemberData member) { if (member.DeclaringType.DescendsTo(resourceTypeData) && member.Name == nameof(Resource.Name)) return true; if (member.GetAttribute() is BrowsableAttribute attr) return attr.Browsable; if (member.HasAttribute()) return true; return member.Attributes.Any(a => a is XmlIgnoreAttribute) == false && member.Writable; } public static TabControl GetControl(object obj, StepSettingView parent) { var tabControl = new TabControl() { BorderThickness = new Thickness(0,1,0,0) }; // 继承 App 级别的所有资源 tabControl.Resources.MergedDictionaries.Add(Application.Current.Resources); Dictionary groupCache = new Dictionary(); StackPanel GetStack(DisplayAttribute display) { string header = display.Header ?? "属性"; StackPanel stack = null; if (!groupCache.ContainsKey(header)) { stack = new StackPanel() { Margin = new Thickness(5) }; var item = new TabItem { Content = stack }; item.SetValue(TabItem.HeaderProperty, new DynamicResourceExtension(header).ProvideValue(null)); item.SetBinding(TabItem.FontSizeProperty, new Binding("FontSize") { Source = parent }); tabControl.Items.Add(item); groupCache.Add(header, item); StackPanelHelper.SetChildSpace(stack, 5); } else { stack = (StackPanel)groupCache[header].Content; } return stack; } var properties = GetRenderProperty(obj); int i = 0; foreach (var key in properties.Keys) { var property = properties[key]; var display = property.GetCustomAttribute(); string header = display.Header ?? "属性"; var stack = GetStack(display); var fg = new FormGroup { Orientation = Orientation.Horizontal, GroupName = $"{header}", VerticalHeaderAlignment = VerticalAlignment.Top }; fg.SetValue(FormGroup.HeaderProperty, new DynamicResourceExtension(display.Name).ProvideValue(null)); stack.Children.Add(fg); var element = FormGroupProvider.RanderElement(obj, display, property); if (element is VariableTextBox vtb) { BindingOperations.SetBinding(vtb, VariableTextBox.SeqProperty, new Binding("Seq") { Source = parent, }); } fg.Content = element; BindingOperations.SetBinding(fg, FormGroup.IsEnabledProperty, new Binding(nameof(StepSettingView.CanEdit)) { Source = parent, }); if (property.GetCustomAttribute() is DependOnAttribute doa) { BindingOperations.SetBinding(fg, FrameworkElement.VisibilityProperty, new Binding(doa.BindingName) { Source = obj, Converter = VisibilityConvertor.Instance, ConverterParameter = doa.TargetValue }); } i++; } foreach (var node in GetRenderMethods(obj)) { var method = node.Value; var display = method.GetCustomAttribute(); var stack = GetStack(display); var btn = new Button { Content = display.Name }; btn.Click += (sender, e) => { method.Invoke(obj, null); }; stack.Children.Add(btn); i++; } //if (obj is ITestStepParent tsp) //{ // grid.RowDefinitions.Add(new RowDefinition() // { // Height = new GridLength(1, GridUnitType.Auto) // }); // var fg = new FormGroup // { // Orientation = Orientation.Horizontal, // Header = "Break Condition", // GroupName = GroupName // }; // grid.Children.Add(fg); // Grid.SetRow(fg, i); // var s = BreakConditionProperty.GetBreakCondition(tsp); // var element = new BreakConditionCtrl // { // Source = tsp // }; // fg.Content = element; //} return tabControl; } } }