为动态添加的TextBox生成ValidationRule属性
动态生成绑定数据库列的TextBox并自动添加必填验证规则
我来帮你搞定这个需求——从数据库读取列信息,为每个列生成TextBox,并且根据列的AllowDBNull属性自动附加必填验证规则。下面是完整的实现步骤和代码示例:
1. 完善必填验证规则类
首先把你提到的NotEmptyValidationRule补全,确保能正确处理null和空字符串的情况:
using System.Globalization; using System.Windows.Controls; public class NotEmptyValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { // 把null值转为空字符串统一判断 var input = value?.ToString() ?? string.Empty; if (string.IsNullOrWhiteSpace(input)) { return new ValidationResult(false, "此字段为必填项,不能为空"); } return ValidationResult.ValidResult; } }
2. 获取数据库列的元数据
这里用ADO.NET的GetSchema方法来获取指定表的列信息,重点提取列名和是否允许为空的属性:
using System.Data; using System.Data.SqlClient; using System.Collections.Generic; // 用来存储列信息的简单实体 public class DbColumn { public string ColumnName { get; set; } public bool AllowDBNull { get; set; } } public List<DbColumn> GetTableColumns(string connectionString, string tableName) { var columns = new List<DbColumn>(); using (var conn = new SqlConnection(connectionString)) { conn.Open(); // 获取指定表的列架构信息 var schema = conn.GetSchema("Columns", new[] { null, null, tableName }); foreach (DataRow row in schema.Rows) { columns.Add(new DbColumn { ColumnName = row["COLUMN_NAME"].ToString(), AllowDBNull = (bool)row["IS_NULLABLE"] }); } } return columns; }
3. 动态生成TextBox并绑定验证规则
遍历获取到的列信息,为每个列创建TextBox,设置数据绑定,并根据AllowDBNull的值决定是否添加必填验证:
using System.Windows; using System.Windows.Controls; using System.Windows.Data; public void CreateTextBoxesForColumns(Panel parentContainer, List<DbColumn> columns, object dataSource) { foreach (var column in columns) { // 创建TextBox控件 var textBox = new TextBox { Width = 220, Margin = new Thickness(8), VerticalAlignment = VerticalAlignment.Center }; // 创建数据绑定,假设你的数据源属性名和列名一致 var binding = new Binding(column.ColumnName) { Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }; // 如果列不允许为空,添加必填验证规则 if (!column.AllowDBNull) { binding.ValidationRules.Add(new NotEmptyValidationRule()); } // 将绑定应用到TextBox的Text属性 textBox.SetBinding(TextBox.TextProperty, binding); // 创建标签显示列名 var label = new Label { Content = $"{column.ColumnName}:", Margin = new Thickness(8), VerticalAlignment = VerticalAlignment.Center }; // 用水平容器放置标签和TextBox var rowPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 4, 0, 4) }; rowPanel.Children.Add(label); rowPanel.Children.Add(textBox); // 添加到父容器(比如窗口的Grid或StackPanel) parentContainer.Children.Add(rowPanel); } // 设置父容器的数据源 parentContainer.DataContext = dataSource; }
4. 在WPF窗口中调用示例
假设你有一个WPF窗口,里面有一个名为MainContainer的StackPanel,这样调用即可:
public MainWindow() { InitializeComponent(); // 替换为你的数据库连接字符串和表名 var connectionString = "YourDatabaseConnectionString"; var tableName = "YourTableName"; // 获取列信息 var columns = GetTableColumns(connectionString, tableName); // 替换为你的实际数据实体(比如从数据库查询出来的对象) var dataItem = new YourDataEntity(); // 生成TextBox到容器中 CreateTextBoxesForColumns(MainContainer, columns, dataItem); }
额外小技巧
- 如果你的数据实体属性名和数据库列名不一致,可以在绑定的时候用
Path或者添加[Display(Name = "列名")]特性来映射。 - 要是需要其他验证规则(比如长度、格式验证),可以参考
NotEmptyValidationRule的写法,创建对应的验证类,然后根据列的其他元数据(比如CHARACTER_MAXIMUM_LENGTH)动态添加。 - 可以自定义
Validation.ErrorTemplate来美化错误提示,比如在TextBox旁边显示红色感叹号或者错误文本,提升用户体验。
内容的提问来源于stack exchange,提问作者KushGene
相关产品推荐
相关产品推荐

