Ich erstelle eine WPF-Anwendung, die ein Formular basierend auf einem Modell erstellt, um es zu bearbeiten. Ich verwende Reflektion, um alle Eigenschaften des Modells durchzugehen, um Eingabefelder für die Eigenschaften zu erstellen. Die GenerateForm-Methode durchläuft die Eigenschaften und verwendet die SimpleInputFactory zum Generieren von Eingabefeldern. Ich möchte die Eingabe der generierten Felder validieren, aber für alle Validierungsmethoden müssen Sie wissen, was Sie validieren möchten (entweder mit Generika oder mit der Bindung im XAML). Ich möchte die Eingabe basierend auf Attributen in den Modellen validieren. Gibt es einen bestehenden Weg dies zu tun? Ich könnte es einfach selbst machen, aber wenn es einen bestehenden Weg gibt, würde es helfen.WPF-Validierungslaufzeit generierte Formulare
Vielen Dank im Voraus.
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;
}
SimpleInputFieldFactory Klasse:
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;
}
}
Danke, das hat funktioniert! Sollte das bemerkt haben. –