C# WPF验证运行时生成的表单
我正在创建一个WPF应用程序,它根据一个模型生成一个表单来编辑它。我使用反射遍历模型的所有属性,为属性创建inputfields。GenerateForm方法遍历属性并使用SimpleInputFactory生成输入字段。我想验证生成字段的输入,但所有验证方法都要求您知道要验证什么(要么使用泛型,要么必须在XAML中的绑定中指定)。我想根据模型中的属性验证输入。有没有现成的方法可以做到这一点?我可以自己做,但如果有现成的方法,它会有所帮助 提前谢谢C# WPF验证运行时生成的表单,c#,wpf,validation,mvvm,C#,Wpf,Validation,Mvvm,我正在创建一个WPF应用程序,它根据一个模型生成一个表单来编辑它。我使用反射遍历模型的所有属性,为属性创建inputfields。GenerateForm方法遍历属性并使用SimpleInputFactory生成输入字段。我想验证生成字段的输入,但所有验证方法都要求您知道要验证什么(要么使用泛型,要么必须在XAML中的绑定中指定)。我想根据模型中的属性验证输入。有没有现成的方法可以做到这一点?我可以自己做,但如果有现成的方法,它会有所帮助 提前谢谢 public static Grid
public static Grid GenerateForm(List<object> basisgegevensModels, AddOrEdit addOrEdit)
{
if (basisgegevensModels.Count <= 0)
return null;
Grid formGrid = new Grid();
formGrid.Margin = new Thickness(20,20,20,20);
formGrid.HorizontalAlignment = HorizontalAlignment.Stretch;
AddColumnToGrid(formGrid, GridUnitType.Star, 1);
AddColumnToGrid(formGrid, GridUnitType.Star, 3);
AddColumnToGrid(formGrid, GridUnitType.Star, 1);
AddColumnToGrid(formGrid, GridUnitType.Star, 3);
AddRowToGrid(formGrid, GridUnitType.Auto, 0);
var propertyInfos = new List<PropertyInfo>();
foreach (var propertyInfo in basisgegevensModels[0].GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance))
{
var visibleAttribute = propertyInfo.GetCustomAttributes(typeof(Visible), false).Cast<Visible>().FirstOrDefault();
if (visibleAttribute == null || visibleAttribute.IsVisible)
propertyInfos.Add(propertyInfo);
}
int column = 0;
int row = 0;
foreach (var property in propertyInfos)
{
if (row >= Math.Ceiling((decimal)propertyInfos.Count / 2) && row != 0 && column != 2)
{
column = 2;
row = 0;
}
var displayNameAttribute = basisgegevensModels[0].GetType().GetProperty(property.Name).GetCustomAttributes(typeof(DisplayNameAttribute), false)
.Cast<DisplayNameAttribute>().FirstOrDefault();
string displayName;
if (displayNameAttribute != null)
displayName = displayNameAttribute.DisplayName;
else
displayName = property.Name;
bool isEditAllowed = true;
if (addOrEdit == AddOrEdit.Edit)
{
var editAllowed =
basisgegevensModels[0].GetType()
.GetProperty(property.Name)
.GetCustomAttributes(typeof (EditAllowed), false)
.Cast<EditAllowed>()
.FirstOrDefault();
if (editAllowed != null)
isEditAllowed = editAllowed.IsEditAllowed;
}
//add label for inputfield
TextBlock label = SimpleInputFieldFactory.CreateTextBlock(displayName, column, row);
label.VerticalAlignment = VerticalAlignment.Center;
formGrid.Children.Add(label);
column++;
//add input field
formGrid.Children.Add(SimpleInputFieldFactory.CreateInputField(basisgegevensModels, property, isEditAllowed, column, row, 300, HorizontalAlignment.Left));
column--;
row++;
if (column == 0)
{
AddRowToGrid(formGrid, GridUnitType.Auto, 0);
}
}
return formGrid;
}
publicstaticgridgenerateform(列出基本网格模型,AddOrEdit AddOrEdit)
{
如果(basisgegevensModels.Count=数学上限((十进制)属性infos.Count/2)&&row!=0&&column!=2)
{
列=2;
行=0;
}
var displayNameAttribute=basisgegevensModels[0].GetType().GetProperty(property.Name).GetCustomAttributes(typeof(displayNameAttribute),false)
.Cast().FirstOrDefault();
字符串显示名;
if(displayNameAttribute!=null)
displayName=displayNameAttribute.displayName;
其他的
displayName=property.Name;
bool isEditAllowed=true;
if(addOrEdit==addOrEdit.Edit)
{
允许的变量=
basisgegevensModels[0]。GetType()
.GetProperty(property.Name)
.GetCustomAttributes(typeof(EditAllowed),false)
.Cast()
.FirstOrDefault();
如果(允许编辑!=null)
isEditAllowed=editAllowed.isEditAllowed;
}
//为inputfield添加标签
TextBlock label=SimpleInputFieldFactory.CreateTextBlock(显示名称、列、行);
label.VerticalAlignment=VerticalAlignment.Center;
formGrid.Children.Add(标签);
列++;
//添加输入字段
formGrid.Children.Add(SimpleInputFieldFactory.CreateInputField(basisgegevensModels,property,isEditAllowed,column,row,300,HorizontalAlignment.Left));
列--;
行++;
如果(列==0)
{
AddRowToGrid(formGrid,GridUnitType.Auto,0);
}
}
返回formGrid;
}
SimpleInputFieldFactory类:
public class SimpleInputFieldFactory
{
public static Control CreateInputField(List<object> basisgegevensModels, PropertyInfo property, bool editAllowed, int column, int row, double inputFieldWidth, HorizontalAlignment inputFieldHorAlignment)
{
Control inputField = null;
var triggers = new List<System.Windows.Interactivity.EventTrigger>();
var multiBinding = new MultiBinding();
multiBinding.NotifyOnSourceUpdated = true;
multiBinding.Mode = BindingMode.TwoWay;
multiBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
foreach (var basisgegevensModel in basisgegevensModels)
{
Binding binding = new Binding(property.Name)
{
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
Source = basisgegevensModel,
Mode = BindingMode.TwoWay
};
multiBinding.Bindings.Add(binding);
}
//add inputfield
if (property.PropertyType == typeof(string) || property.PropertyType == typeof(int))
{
string valueAsString = "";
if (property.GetValue(basisgegevensModels[0]) != null)
valueAsString = property.GetValue(basisgegevensModels[0]).ToString();
inputField = CreateTextBox(valueAsString, column, row);
triggers.Add(new System.Windows.Interactivity.EventTrigger("EditValueChanged"));
}
else if (property.PropertyType == typeof(bool))
{
bool valueAsBool = false;
if (property.GetValue(basisgegevensModels[0]) != null)
valueAsBool = (bool)property.GetValue(basisgegevensModels[0]);
inputField = CreateCheckBox(valueAsBool, column, row);
triggers.Add(new System.Windows.Interactivity.EventTrigger("EditValueChanged"));
}
else if (property.PropertyType.BaseType == typeof(Enum))
{
int valueAsInt = 0;
if (property.GetValue(basisgegevensModels[0]) != null)
valueAsInt = (int)property.GetValue(basisgegevensModels[0]);
inputField = CreateDropDown(property.PropertyType, valueAsInt, column, row);
triggers.Add(new System.Windows.Interactivity.EventTrigger("EditValueChanged"));
((ComboBoxEdit)inputField).SelectedIndex = valueAsInt;
((ComboBoxEdit)inputField).IsTextEditable = false;
}
//add general settings, bindings and triggers
if (inputField != null)
{
inputField.Width = inputFieldWidth;
inputField.HorizontalAlignment = inputFieldHorAlignment;
inputField.Margin = new Thickness(5);
inputField.IsEnabled = editAllowed;
var multiEditAllowedAttribute = property.GetCustomAttributes(typeof(MultiEditAllowed), false)
.Cast<MultiEditAllowed>().FirstOrDefault();
//only add binding and trigger if 1 entity is selected OR multiedit is allowed
if (basisgegevensModels.Count == 1 || multiEditAllowedAttribute == null || multiEditAllowedAttribute.IsMultiEditAllowed)
{
multiBinding.Converter = new MultiEditValueConverter();
inputField.SetBinding(BaseEdit.EditValueProperty, multiBinding);
foreach (var trigger in triggers)
{
var action = new ActionMessage();
action.MethodName = "InputChanged";
trigger.Actions.Add(action);
Interaction.GetTriggers(inputField).Add(trigger);
}
}
else
{
inputField.IsEnabled = false;
}
return inputField;
}
return null;
}
public static List<string> GetEnumList(Type enumType)
{
if (!enumType.IsEnum)
{
return new List<string>();
}
return Enum.GetNames(enumType).ToList();
}
public static TextBlock CreateTextBlock(string text, int column, int row)
{
TextBlock textBlock = new TextBlock();
textBlock.Text = text;
Grid.SetColumn(textBlock, column);
Grid.SetRow(textBlock, row);
return textBlock;
}
private static TextEditBase CreateTextBox(string text, int column, int row)
{
TextEdit textBox = new TextEdit();
textBox.Text = text;
Grid.SetColumn(textBox, column);
Grid.SetRow(textBox, row);
return textBox;
}
private static CheckEdit CreateCheckBox(bool isChecked, int column, int row)
{
CheckEdit checkBox = new CheckEdit();
checkBox.IsChecked = isChecked;
Grid.SetColumn(checkBox, column);
Grid.SetRow(checkBox, row);
return checkBox;
}
private static ComboBoxEdit CreateDropDown(Type enumType, int value, int column, int row)
{
ComboBoxEdit dropDown = new ComboBoxEdit();
foreach (var enumValue in GetEnumList(enumType))
{
dropDown.Items.Add(enumValue);
}
dropDown.SelectedIndex = value;
Grid.SetColumn(dropDown, column);
Grid.SetRow(dropDown, row);
return dropDown;
}
}
公共类SimpleInputFieldFactory
{
公共静态控件CreateInputField(列出基本GegEventsModels、PropertyInfo属性、bool editAllowed、int列、int行、double inputFieldWidth、HorizontalAlignment inputFieldHorAlignment)
{
控制输入字段=null;
var触发器=新列表();
var multiBinding=新的multiBinding();
multiBinding.NotifyOnSourceUpdated=true;
multiBinding.Mode=BindingMode.TwoWay;
multiBinding.UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged;
foreach(basisgegevensModel中的var basisgegevensModel)
{
Binding Binding=新绑定(property.Name)
{
UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged,
Source=基本几何几何模型,
Mode=BindingMode.TwoWay
};
multiBinding.Bindings.Add(绑定);
}
//添加输入字段
if(property.PropertyType==typeof(string)| | property.PropertyType==typeof(int))
{
字符串值字符串=”;
if(property.GetValue(basisgegevensModels[0])!=null)
valueAsString=property.GetValue(BasisGetEventsModels[0]).ToString();
inputField=CreateTextBox(值字符串、列、行);
添加(new System.Windows.Interactivity.EventTrigger(“EditValueChanged”);
}
else if(property.PropertyType==typeof(bool))
{
bool valueAsBool=false;
if(property.GetValue(basisgegevensModels[0])!=null)
valueAsBool=(bool)属性.GetValue(BasisGetEventsModels[0]);
inputField=CreateCheckBox(valueAsBool、列、行);
添加(new System.Windows.Interactivity.EventTrigger(“EditValueChanged”);
}
else if(property.PropertyType.BaseType==typeof(枚举))
{
int valueAsInt=0;
if(property.GetValue(basisgegevensModels[0])!=null)
valueAsInt=(int)property.GetValue(basisGetEventsModels[0]);
inputField=CreateDropDown(property.PropertyType、valueAsInt、列、行);
添加(new System.Windows.Interactivity.EventTrigger(“EditValueChanged”);
((ComboBoxEdit)inputField)。选择Dex=valueAsInt;
((Comboboboxedit)inputField).IsTextEditable=false;
}
//添加常规设置、绑定和触发器
如果(输入字段!=null)
{
inputField.Width=inputFieldWidth;
inputField.HorizontalAlignment=inputFieldHorAlignment;
输入字段。边距=新厚度(5);
inputField.IsEnabled=editAllowed;
var multiEditAllowedAttribute=property.GetCustomAttributes(typeof(MultiEditAllowed),false)
.Cast().FirstOrDefault();
//仅在选择1个实体或允许多重编辑时添加绑定和触发器
if(basisgegevensModels.Count==1 | | multiEditAllowedAttribute==null | | multiEditAllowedAttribute.IsMultiEditAllowed允许)
{
multiBinding.Converter=新的MultiEditValueConverter();
inputField.SetBinding(BaseEdit.EditValueProperty,多重绑定);
foreach(触发器中的var触发器)