は、私はあなたがちょうどあなた自身を記述することをお勧めしたいです。ラベル付きコントロールの垂直リストを持つフォームの最も基本的なケースでは、私の直感的なアプローチは、文字列オブジェクトペアの順序付けられたリストで構成されたデータオブジェクトを持つことです(多分、検証規則でトリプルにすることもできます)。フォームがロードされるときに各オブジェクトのタイプがチェックされ、文字列であればテキストボックスを作成します。ブールであればチェックボックスなどを作成します。 たとえば、intやdoubleなどがある場合は入力の検証ができます。もう一方の方向はあまりにも硬くはありません。
私は、次の(WPF)のように前にセミダイナミック汎用の編集ダイアログを書いた: ウィンドウの内容の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>
:
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]);
}
}
}
使用例:
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;
}
カスタムコンストラクタ、編集ボタンなどでは、完全に動的なダイアログにすることができます。レイアウトがどれほど洗練されているかによって、多かれ少なかれ動作する可能性があります。もちろん、それを行うライブラリを見つけるのが最も簡単です。多分誰かがそれを知っているかもしれません。