Ich würde vorschlagen, dass Sie Ihre eigenen nur schreiben. Im einfachsten Fall eines Formulars mit einer vertikalen Liste beschrifteter Steuerelemente wäre mein intuitiver Ansatz, ein Datenobjekt zu haben, das aus einer geordneten Liste von String-Objekt-Paaren besteht (vielleicht auch ein Tripel mit einer Validierungsregel), Wenn das Formular geladen werden soll, wird der Typ jedes Objekts überprüft und wenn es ein String ist, erstellen Sie ein Textfeld, wenn es ein Bool ist, erstellen Sie ein Kontrollkästchen usw. Sie können auch eine Eingabe-Validierung haben, wenn Sie zB int und doubles haben. Die andere Richtung sollte auch nicht zu schwer sein.
Ich habe geschrieben semi-dynamische generic bearbeiten Dialoge vor wie folgt (WPF): Fenster Inhalt XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Name="StackPanelInput" Grid.Row="0" Orientation="Vertical" VerticalAlignment="Top" Margin="5"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="5">
<Button Name="ButtonOK" HorizontalAlignment="Right" Width="100" Margin="5" Click="ButtonOK_Click" IsDefault="True">OK</Button>
<Button Name="ButtonCancel" HorizontalAlignment="Right" Width="100" Margin="5" Click="ButtonCancel_Click" IsCancel="True">Cancel</Button>
</StackPanel>
</Grid>
-Code-behind:
public partial class EditDialog : Window
{
private List<Control> Controls = new List<Control>();
public EditDialog()
{
InitializeComponent();
Loaded += delegate { KeyboardFocusFirstControl(); };
}
public EditDialog(string dialogTitle) : this()
{
Title = dialogTitle;
}
private void ButtonOK_Click(object sender, RoutedEventArgs e)
{
(sender as Button).Focus();
if (!IsValid(this))
{
MessageBox.Show("Some inputs are currently invalid.");
return;
}
DialogResult = true;
}
private void ButtonCancel_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
bool IsValid(DependencyObject node)
{
if (node != null)
{
bool isValid = !Validation.GetHasError(node);
if (!isValid)
{
if (node is IInputElement) Keyboard.Focus((IInputElement)node);
return false;
}
}
foreach (object subnode in LogicalTreeHelper.GetChildren(node))
{
if (subnode is DependencyObject)
{
if (IsValid((DependencyObject)subnode) == false) return false;
}
}
return true;
}
public TextBox AddTextBox(string label, ValidationRule validationRule)
{
Grid grid = new Grid();
grid.Height = 25;
grid.Margin = new Thickness(5);
ColumnDefinition colDef1 = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };
ColumnDefinition colDef2 = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };
grid.ColumnDefinitions.Add(colDef1);
grid.ColumnDefinitions.Add(colDef2);
Label tbLabel = new Label() { Content = label };
tbLabel.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
grid.Children.Add(tbLabel);
TextBox textBox = new TextBox();
Binding textBinding = new Binding("Text");
textBinding.Source = textBox;
textBinding.ValidationRules.Add(validationRule);
textBox.SetBinding(TextBox.TextProperty, textBinding);
textBox.GotKeyboardFocus += delegate { textBox.SelectAll(); };
textBox.TextChanged += delegate { textBox.GetBindingExpression(TextBox.TextProperty).ValidateWithoutUpdate(); };
textBox.Text = "";
textBox.GetBindingExpression(TextBox.TextProperty).ValidateWithoutUpdate();
Grid.SetColumn(textBox, 1);
grid.Children.Add(textBox);
StackPanelInput.Children.Add(grid);
Controls.Add(textBox);
return textBox;
}
public TextBox AddTextBox(string label, ValidationRule validationRule, string defaultText)
{
TextBox tb = AddTextBox(label, validationRule);
tb.Text = defaultText;
return tb;
}
public CheckBox AddCheckBox(string label)
{
Grid grid = new Grid();
grid.Height = 25;
grid.Margin = new Thickness(5);
CheckBox cb = new CheckBox();
cb.VerticalAlignment = System.Windows.VerticalAlignment.Center;
cb.Content = label;
grid.Children.Add(cb);
StackPanelInput.Children.Add(grid);
Controls.Add(cb);
return cb;
}
private void KeyboardFocusFirstControl()
{
if (Controls.Count > 0)
{
Keyboard.Focus(Controls[0]);
}
}
}
Anwendungsbeispiel:
EditDialog diag = new EditDialog();
TextBox firstName = diag.AddTextBox("First Name:", new StringValidationRule());
TextBox lastName = diag.AddTextBox("Last Name:", new StringValidationRule());
TextBox age = diag.AddTextBox("Age:", new IntegerValidationRule(1,int.MaxValue));
if ((bool)diag.ShowDialog())
{
//parse texts and write them to some data;
}
Mit einigen benutzerdefinierten Konstruktoren, Schaltflächen bearbeiten und dergleichen bin ich sicher, dass Sie in der Lage sein werden, es in einen voll dynamischen Dialog zu verwandeln. Je nachdem, wie ausgefeilt das Layout sein sollte, könnte das mehr oder weniger funktionieren. Natürlich wäre es am einfachsten, eine Bibliothek zu finden, die genau das tut.