2011-01-10 61 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; 
} 

隨着一些自定義的構造函數,編輯按鈕等我相信你可以把它變成一個完全動態的對話。取決於多麼複雜的佈局應該是可能是或多或少的工作。當然,找到一個能夠做到這一點的圖書館是最簡單的,也許有人知道其中一個。