2011-01-10 69 views
0

我们有一个桌面应用程序,基本上为特定的部门(例如运输)建模作业,其中包括工作日期,参考资料,驱动程序分配等,然后发送到PDA或从PDA发送状态更新。用客户指定的附加动态字段创建表单?

尽管它主要是现成的,但我们通常最终不得不为了适应公司而做定制部件,其中大约90%的时间只有额外的数据字段不需要任何逻辑,只能存储/检索。

我一直在寻找一个基本的拖放库来将表单转换为可编辑模式,我可以保存位置,组件类型,默认值和运行时在非编辑模式下填充,但没有真正能找到一个。

是最好的方法来推出自己的或我错过了一个图书馆,会让我60%的方式吗? WPF或Winforms的帮助将不胜感激(我们正在使用Winforms,但转移到WPF)。

干杯,

托马斯

回答

0

我建议你只写你自己的。在带有垂直标签控件列表的最基本的情况下,我的直观方法是创建一个数据对象,它包含一个字符串对象对的有序列表(也可以将它作为带验证规则的三元组),当表单应该被加载时,每个对象的类型都会被检查,如果它是一个字符串,你创建一个文本框,如果它是一个布尔值,你创建一个复选框等。 如果你有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; 
} 

随着一些自定义的构造函数,编辑按钮等我相信你可以把它变成一个完全动态的对话。取决于多么复杂的布局应该是可能是或多或少的工作。当然,找到一个能够做到这一点的图书馆是最简单的,也许有人知道其中一个。