C# C语言中的动态UI生成#
我正在为图书馆设计一个应用程序。不是一个大型图书馆,而是一个非常小的图书馆,我的主要任务是保存有关书籍的信息。但是这个库应用程序应该能够适应任何专业人员的私有库。例如,对于律师来说,除了书的基本信息(标题、作者、出版商等),可能还有其他与书相关的特殊字段(案件编号、法院编号等)。医生可能对一本书有其他一些特殊属性。其他职业也是如此 因此,我将使用一个SQLServerCE数据库,我希望有一个具有常规属性的BOOK表,并根据需要更改该表以满足特殊需要(添加更多列) 但我担心的是动态生成GUI以支持新属性 有什么方法可以解决动态GUI生成问题吗 我不是要完整的代码(显然我不会得到),但是如果你有任何代码来支持这种方法,请发邮件:)C# C语言中的动态UI生成#,c#,user-interface,dynamic,sql-server-ce,C#,User Interface,Dynamic,Sql Server Ce,我正在为图书馆设计一个应用程序。不是一个大型图书馆,而是一个非常小的图书馆,我的主要任务是保存有关书籍的信息。但是这个库应用程序应该能够适应任何专业人员的私有库。例如,对于律师来说,除了书的基本信息(标题、作者、出版商等),可能还有其他与书相关的特殊字段(案件编号、法院编号等)。医生可能对一本书有其他一些特殊属性。其他职业也是如此 因此,我将使用一个SQLServerCE数据库,我希望有一个具有常规属性的BOOK表,并根据需要更改该表以满足特殊需要(添加更多列) 但我担心的是动态生成GUI以支持
关于优点、缺点、死胡同、注意事项或警告等,有什么我应该知道的吗?我不知道动态更改表是否是一个好的设计决策。您可以使用一个查找表(可以在其中定义详细信息类型)和一个图书详细信息表(可以在其中存储这些详细信息)。然后,您可以在图书编辑部分以datagrid的形式显示这些详细信息,datagrid的详细信息类型为行,每行有一列,您可以在其中编辑值。当然,一本书的细节可以是简单的字符串值以外的任何内容,但这可以轻松处理。希望我足够清楚:)
在@devnull拾取的数据模型端,您正在描述一个自定义字段实现,@devnull正在描述模型 有一篇很好的stackoverflow文章介绍了应用程序中自定义字段的设计模式: 数据模型选择和UI生成紧密相连,因此在决定数据模型/自定义字段模式之前,您无法真正回答UI生成问题。我最初的反应与@devnull对alter方法的反应相同,但实际上没有很好的解决方案 如果您有一个所有可能字段的超集,并允许用户启用/禁用适合其应用程序域的字段,则可以降低很多复杂性。我在一个应用程序中与非常聪明的人一起实现了几个自定义字段,这总是很困难的。如果你对应用领域有足够的了解,你就可以远离优步灵活的体系结构,省去很多痛苦
注意,一个重要的考虑因素是他们是否需要查询自定义字段。如果您不必支持一般查询,那么这会容易得多。您只需为userdate1、usern等设置插槽,并为标签提供元数据表。有很多代码生成工具可用。其中一些生成的代码具有易于使用的GUI 或者,以下代码可以让您的生活更轻松 您可以为以下实体创建一个通用的基本表单:
public partial class BaseForm : Form
{
///////////Event Mechanism///////////
protected internal event ItemStateChanged ItemStateChangeEvent;
protected internal void OnItemStateChanged()
{
if (ItemStateChangeEvent != null)
{
ItemStateChangeEvent();
}
}
///////////Event Mechanism///////////
protected internal Label ErrorMessageTextBox
{
get { return this.errorMessageTextBox; }
set { this.errorMessageTextBox = value; }
}
protected internal ToolStripStatusLabel TotalToolStripStatusLabel
{
get { return this.totalToolStripStatusLabel; }
set { this.totalToolStripStatusLabel = value; }
}
protected internal FormViewMode FormViewMode { get; set; }
public BaseForm()
{
InitializeComponent();
}
}
和集合的一般基本形式:
public partial class CollectionBaseForm : BaseForm
{
protected internal ToolStripMenuItem ReportMenu { get { return this.reportsToolStripMenuItem; } set { this.reportsToolStripMenuItem = value; } }
protected internal DataGridView DataGridView { get {return this.dataGridView1 ;} set {dataGridView1 = value ;} }
protected internal Button SearchButton { get { return btnSearch; } set { btnSearch = value; } }
protected internal Button AddNewButton { get { return btnAddNew; } set { btnAddNew = value; } }
protected internal Button EditButton { get { return btnEdit; } set { btnEdit = value; } }
protected internal Button DeleteButton { get { return btnDelete; } set { btnDelete = value; } }
protected internal Button PickButton { get { return btnPick; } set { btnPick = value; } }
private FormViewMode _formViewMode;
public FormViewMode FormViewMode
{
get
{
return _formViewMode;
}
set
{
_formViewMode = value;
EnableDisableAppropriateButtons(_formViewMode);
}
}
private void EnableDisableAppropriateButtons(FormViewMode FormViewMode)
{
if (FormViewMode == FormViewMode.Collection)
{
AddNewButton.Enabled = true;
EditButton.Enabled = true;
DeleteButton.Enabled = true;
PickButton.Enabled = false;
}
else if (FormViewMode == FormViewMode.Picker)
{
AddNewButton.Enabled = false;
EditButton.Enabled = false;
DeleteButton.Enabled = false;
PickButton.Enabled = true;
}
}
public CollectionBaseForm()
{
InitializeComponent();
this.MaximumSize = this.MinimumSize = this.Size;
this.FormViewMode = FormViewMode.Collection;
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
}
}
然后,所有表单都将具有相同的总体外观:
这可能会有所帮助,它不是动态的,但很容易适应
您开发的平台是什么?可移动的网状物桌面?我正在使用C#为桌面开发。谢谢你,德夫努尔。这是一个非常好的主意,我也提出了类似的想法。但问题是我只能存储特定的数据类型。请你解释一下为什么改变桌子不是一个好的设计决定好吗?:)因为依赖于该表的所有内容都需要更新以反映这些更改。拥有一个固定且一致的模式可以在数据存储和应用程序之间实现清晰的分离。如果您计划编写一个使用同一数据库的webapp,则必须复制处理数据库架构更新的代码。另外,动态更改表的1是一个错误的设计决策。不幸的是,自定义字段需要查询。依我看,如果用户不能正确搜索,自定义字段将没有多大用处?
public partial class CollectionBaseForm : BaseForm
{
protected internal ToolStripMenuItem ReportMenu { get { return this.reportsToolStripMenuItem; } set { this.reportsToolStripMenuItem = value; } }
protected internal DataGridView DataGridView { get {return this.dataGridView1 ;} set {dataGridView1 = value ;} }
protected internal Button SearchButton { get { return btnSearch; } set { btnSearch = value; } }
protected internal Button AddNewButton { get { return btnAddNew; } set { btnAddNew = value; } }
protected internal Button EditButton { get { return btnEdit; } set { btnEdit = value; } }
protected internal Button DeleteButton { get { return btnDelete; } set { btnDelete = value; } }
protected internal Button PickButton { get { return btnPick; } set { btnPick = value; } }
private FormViewMode _formViewMode;
public FormViewMode FormViewMode
{
get
{
return _formViewMode;
}
set
{
_formViewMode = value;
EnableDisableAppropriateButtons(_formViewMode);
}
}
private void EnableDisableAppropriateButtons(FormViewMode FormViewMode)
{
if (FormViewMode == FormViewMode.Collection)
{
AddNewButton.Enabled = true;
EditButton.Enabled = true;
DeleteButton.Enabled = true;
PickButton.Enabled = false;
}
else if (FormViewMode == FormViewMode.Picker)
{
AddNewButton.Enabled = false;
EditButton.Enabled = false;
DeleteButton.Enabled = false;
PickButton.Enabled = true;
}
}
public CollectionBaseForm()
{
InitializeComponent();
this.MaximumSize = this.MinimumSize = this.Size;
this.FormViewMode = FormViewMode.Collection;
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
}
}