using OpenTap;
using OpenTap.Addin.Annotation;
using OpenTapEditor.UI;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Xml.Serialization;
namespace OpenTapEditor.Provider
{
public class GridControlProvider
{
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;
}
private static FrameworkElement RanderElement(object source, PropertyInfo property)
{
if (property.GetCustomAttribute() is FilePathAttribute fpa)
{
FileSelector fs = new FileSelector() { Mode = fpa.Mode, Ext = fpa.FileExtension };
if (property.PropertyType == typeof(MacroString))
{
BindingOperations.SetBinding(fs, FileSelector.FilePathProperty,
new Binding(property.Name)
{
Source = source,
Converter = MacroStringConverter.Instance,
ConverterParameter = source,
Mode = BindingMode.TwoWay,
NotifyOnSourceUpdated = true
});
}
else
{
BindingOperations.SetBinding(fs, FileSelector.FilePathProperty,
new Binding(property.Name)
{
Source = source,
Mode = BindingMode.TwoWay,
NotifyOnSourceUpdated = true
});
}
return fs;
}
if (property.GetCustomAttribute() is DynamicSelectAttribute dsa)
{
ComboBox combox = new ComboBox();
if (!string.IsNullOrEmpty(dsa.SourceName))
{
BindingOperations.SetBinding(combox, ComboBox.ItemsSourceProperty,
new Binding(dsa.SourceName)
{
Source = source,
Mode = BindingMode.OneWay
});
}
if (!string.IsNullOrEmpty(dsa.DisplayName))
{
combox.DisplayMemberPath = dsa.DisplayName;
combox.SelectedValuePath = dsa.BindingName;
BindingOperations.SetBinding(combox, ComboBox.SelectedValueProperty, new Binding(property.Name)
{
Source = source,
Mode = BindingMode.TwoWay
});
}
else
{
BindingOperations.SetBinding(combox, ComboBox.TextProperty, new Binding(property.Name)
{
Source = source,
Mode = BindingMode.TwoWay
});
}
return combox;
}
if (property.GetCustomAttribute() is BindingListAttribute bla)
{
var dataGrid = new DataGrid()
{
MinHeight = 100,
HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled
};
BindingOperations.SetBinding(dataGrid,
DataGrid.ItemsSourceProperty,
new Binding(bla.BindingName)
{
Source = source,
Mode = BindingMode.TwoWay,
});
dataGrid.CanUserAddRows = bla.CanAdd;
dataGrid.AutoGenerateColumns = false;
dataGrid.CanUserSortColumns = false;
Type propertyType = source?.GetType()?.GetProperty(bla.BindingName)?.PropertyType;
if (propertyType?.IsGenericType == true)
{
DataGridHelper.SetDataGridColumns(dataGrid, propertyType.GetGenericArguments()[0]);
}
else
{
DataGridHelper.SetDataGridColumns(dataGrid, propertyType);
}
return dataGrid;
}
if (property.PropertyType == typeof(bool?) || property.PropertyType == typeof(bool))
{
CheckBox cb = new CheckBox();
cb.VerticalAlignment = VerticalAlignment.Center;
BindingOperations.SetBinding(cb, CheckBox.IsCheckedProperty,
new Binding(property.Name)
{
Source = source,
Mode = BindingMode.TwoWay,
});
return cb;
}
// 枚举
if (property.PropertyType.IsEnum)
{
ComboBox combox = new ComboBox();
combox.VerticalAlignment = VerticalAlignment.Center;
combox.ItemsSource = System.Enum.GetNames(property.PropertyType);
BindingOperations.SetBinding(combox, ComboBox.SelectedItemProperty,
new Binding(property.Name)
{
Source = source,
Mode = BindingMode.TwoWay
});
return combox;
}
/// 参数
if (property.GetCustomAttribute() is TreeDataAttribute tda)
{
VariableTree tree = new VariableTree() { MinHeight = 100 };
BindingOperations.SetBinding(tree, VariableTree.DatasourceProperty,
new Binding(property.Name)
{
Source = source,
Mode = BindingMode.TwoWay
});
return tree;
}
if (property.GetCustomAttribute() is IgnoreVariable iv)
{
TextBox tb = new TextBox
{
IsReadOnly = !(property.CanWrite && property.SetMethod?.IsPublic == true)
};
BindingOperations.SetBinding(tb, TextBox.TextProperty,
new Binding(property.Name)
{
Source = source,
Mode = tb.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
});
return tb;
}
VariableTextBox vtb = new VariableTextBox() { Step = (ITestStep)source };
BindingOperations.SetBinding(vtb, VariableTextBox.ValueProperty,
new Binding(property.Name)
{
Source = source,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
});
return vtb;
}
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 Grid GetControl(object obj)
{
var grid = new Grid()
{
};
grid.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(1, GridUnitType.Auto)
});
grid.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(1, GridUnitType.Star)
});
var properties = GetRenderProperty(obj);
int i = 0;
foreach (var key in properties.Keys)
{
var property = properties[key];
var display = property.GetCustomAttribute();
var label = new Label
{
Content = display.Name
};
grid.RowDefinitions.Add(new RowDefinition()
{
Height = new GridLength(1, GridUnitType.Auto)
});
grid.Children.Add(label);
Grid.SetRow(label, i);
Grid.SetColumn(label, 0);
var element = RanderElement(obj, property);
if (element != null)
{
grid.Children.Add(element);
Grid.SetRow(element, i);
Grid.SetColumn(element, 1);
}
i++;
}
foreach (var node in GetRenderMethods(obj))
{
var method = node.Value;
var display = method.GetCustomAttribute();
var btn = new Button
{
Content = display.Name
};
btn.Click += (sender, e) =>
{
method.Invoke(obj, null);
};
grid.RowDefinitions.Add(new RowDefinition()
{
Height = new GridLength(1, GridUnitType.Auto)
});
grid.Children.Add(btn);
Grid.SetRow(btn, i);
Grid.SetColumn(btn, 0);
Grid.SetColumnSpan(btn, 2);
i++;
}
if (obj is ITestStepParent tsp)
{
grid.RowDefinitions.Add(new RowDefinition()
{
Height = new GridLength(1, GridUnitType.Auto)
});
var label = new Label
{
Content = "Break Condition"
};
grid.Children.Add(label);
Grid.SetRow(label, i);
Grid.SetColumn(label, 0);
var s = BreakConditionProperty.GetBreakCondition(tsp);
var element = new BreakConditionCtrl
{
Source = tsp
};
if (element != null)
{
grid.Children.Add(element);
Grid.SetRow(element, i);
Grid.SetColumn(element, 1);
}
}
return grid;
}
}
}