gpt4 book ai didi

C# 动态表单(反射)-链接控件

转载 作者:行者123 更新时间:2023-11-30 01:26:41 24 4
gpt4 key购买 nike

抱歉,标题质量很差。我想不出更好的方式来表达这一点。

对于我目前正在与几个 friend 合作的项目,我遇到了这样的情况:我创建了一个动态表单(带有反射),现在我想验证它。

示例(忽略黑框,它包含现在不相关的旧表单元素,我不想让你们感到困惑):

Dynamic form with reflection

正如您可能已经猜到的,它是一个用于创建 mysql 数据库的应用程序。这就是我遇到问题的地方。如果其他复选框被选中,我想禁用复选框。

例如:如果我选中“PrimaryKey”,我想禁用“Null”复选框。从无符号更改为有符号会更改 numericupdown 最小值和最大值等。

但是通过反射等等,我发现很难确切地知道要禁用哪个复选框。希望大家给点建议。

我思考这个问题有一段时间了,我想到了一些想法。也许这些是比当前更好的解决方案。

想法 1:我为每种数据类型创建 UserControl。优点:反射没有问题,并且可以轻松识别 UserControl 中的每个控件以进行验证。缺点:复制粘贴、大量用户控件,并且有很多相同的控件。

想法 2:对类的每个属性的描述标签进行一些处理。在描述中创建规则,允许我将复选框链接在一起。在这里,我只需将规则复制到每个类属性,然后就可以了。

我一直在考虑其他解决方案,但我记不住了。希望大家能给我一些好的指导/建议。

[编辑]也许我的代码可以解释更多一点。我的代码:

PropertyInfo[] properties = DataTypes.DataTypes.GetTypeFromString(modelElement.DataType.ToString()).GetType().GetProperties();
foreach (PropertyInfo prop in properties)
{
if (prop.Name != "Label" && prop.Name != "Project" && prop.Name != "Panel")
{
var value = prop.GetValue(modelElement.DataType, null);

if (value != null)
{
tableLayoutPanel1.Controls.Add(new Label { Text = prop.Name, Anchor = AnchorStyles.Left, AutoSize = true });

switch (value.GetType().ToString())
{
case "System.Int32":
NumericUpDown numericUpDown = new NumericUpDown();
numericUpDown.Text = value.ToString();
numericUpDown.Dock = DockStyle.None;
tableLayoutPanel1.Controls.Add(numericUpDown);

break;
case "System.Boolean":
CheckBox checkBox = new CheckBox();
checkBox.Dock = DockStyle.None;

// checkbox will become huge if not for these changes
checkBox.AutoSize = false;
checkBox.Size = new Size(16, 16);

if (value.Equals(true))
{
checkBox.CheckState = CheckState.Checked;
}
tableLayoutPanel1.Controls.Add(checkBox);

break;
default:
MessageBox.Show(@"The following type has not been implemented yet: " + value.GetType());

break;
}
}
}
}

最佳答案

这是我的评论的模型:

// The ViewModel is responsible for handling the actual visual layout of the form.
public class ViewModel {

// Fire this when your ViewModel changes
public event EventHandler WindowUpdated;

public Boolean IsIsNullCheckBoxVisible { get; private set; }

// This method would contain the actual logic for handling window changes.
public void CalculateFormLayout() {

Boolean someLogic = true;

// If the logic is true, set the isNullCheckbox to true
if (someLogic) {
IsIsNullCheckBoxVisible = true;
}

// Inform the UI to update
UpdateVisual();
}

// This fires the 'WindowUpdated' event.
public void UpdateVisual() {
if (WindowUpdated != null) {
WindowUpdated(this, new EventArgs());
}
}

}

public class TheUI : Form {

// Attach to the viewModel;
ViewModel myViewModel = new ViewModel();
CheckBox isNullCheckBox = new CheckBox();

public TheUI() {
this.myViewModel.WindowUpdated += myViewModel_WindowUpdated;
}

void myViewModel_WindowUpdated(object sender, EventArgs e) {
// Update the view here.

// Notie that all we do in the UI is to update the visual based on the
// results from the ViewModel;
this.isNullCheckBox.Visible = myViewModel.IsIsNullCheckBoxVisible;
}

}

这里的基本思想是确保 UI 执行的操作尽可能少。它的作用应该只是更新。更新什么?这是由 ViewModel 类决定的。我们在 ViewModel 类中执行所有更新逻辑,然后当更新计算完成后,我们调用 UpdateVisual() 事件,该事件告诉 UI 它需要来代表自己。当 WindowUpdated 事件发生时,UI 仅通过显示 ViewModel 设置的配置进行响应。

一开始设置这似乎需要做很多工作,但一旦到位,它将为您节省大量的时间。如果您有任何疑问,请告诉我。

关于C# 动态表单(反射)-链接控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17926808/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com