Создание динамического пользовательского интерфейса в C #

Я разрабатываю приложение для библиотеки. Не большая библиотека, но очень маленькая библиотека, где моя основная задача - просто хранить информацию о книгах. Но это библиотечное приложение должно быть в состоянии адаптироваться к личной библиотеке любого профессионала. Например, для юриста, помимо основной информации о книге (название, автор, издатель и т. Д.), Могут быть другие специальные поля, связанные с книгой (номер дела, номер суда и т. Д.). Врач может иметь некоторые другие специальные атрибуты для книги. То же самое касается других профессий.

Итак, я собираюсь использовать базу данных SQL Server CE и надеюсь, что у меня будет таблица BOOK с обычными атрибутами и по требованию ALTER таблицы для удовлетворения особых потребностей (добавьте больше столбцов).

Но мое беспокойство генерирует графический интерфейс динамически для поддержки новых атрибутов.

Существуют ли какие-либо подходы к созданию динамического графического интерфейса?

Я не прошу полный код (который, очевидно, не получу), но если у вас есть какой-либо код для поддержки этого подхода, пожалуйста, будьте любезны опубликовать это :)

Что я должен знать о плюсах, минусах, тупиках, предостережениях или предупреждениях и т. д.?

8
задан tshepang 17 November 2013 в 00:22
поделиться

3 ответа

Что касается модели данных, которую подхватил @devnull, вы описываете реализацию настраиваемых полей, а @devnull описывает модель EAV.

Есть хорошая статья stackoverflow, в которой рассматриваются шаблоны проектирования для настраиваемых полей в приложении:

Какие шаблоны проектирования поддерживают настраиваемые поля в приложении?

Выбор модели данных и создание пользовательского интерфейса тесно связаны, поэтому вы не сможете ответить на вопрос о создании пользовательского интерфейса, пока не определитесь со своей моделью данных/шаблоном пользовательского поля. Моя первоначальная реакция была такой же, как у @devnull в отношении альтернативного подхода, но на самом деле отличного решения нет.

Вы можете значительно снизить сложность, если у вас будет расширенный набор всех возможных полей и вы позволите пользователю включать/отключать те из них, которые подходят для его предметной области. Я сделал несколько реализаций настраиваемых полей в приложении с очень умными людьми, и это всегда сложно. Если вы достаточно хорошо разбираетесь в предметной области, вы можете держаться подальше от сверхгибких архитектур и избавить себя от многих проблем.

Обратите внимание, что важным соображением является вопрос о том, нужно ли им запрашивать настраиваемые поля. Это намного проще, если вам не нужно поддерживать общие запросы. Вы просто добавляете userdate1, usern и т. д. и предоставляете таблицу метаданных для меток.

5
ответ дан 5 December 2019 в 12:53
поделиться

Я не знаю, является ли динамическое изменение таблицы хорошим дизайнерским решением. Вместо этого у вас может быть таблица поиска, в которой вы можете определить типы сведений, и таблица сведений о книгах, в которой вы будете хранить эти сведения. Затем вы можете отобразить эти сведения в разделе редактирования книги в виде сетки данных, в которой типы сведений представлены в виде строк, причем в каждой строке есть столбец, в котором вы будете редактировать значение. Конечно, сведения о книге могут быть чем угодно, кроме простого строкового значения, но с этим можно легко справиться. Надеюсь, я выразился достаточно ясно :)

-------------           -----------------          ----------------
|  Books    |           |  BooksDetail  |          |  DetailTypes |
-------------           -----------------          ----------------
| ID (PK)   | 1      n  | ID (PK)       | 1     1  | ID (PK)      |
| AuthorID  | --------> | BookID        | -------> | Name         |
| Title     |           | DetailID      |          | Description  |
| Year      |           | Value         |          ----------------
-------------           -----------------
4
ответ дан 5 December 2019 в 12:53
поделиться

Существует множество инструментов для генерации кода. Некоторые из них генерируют код с удобным графическим интерфейсом.

MyGeneration

CodeNGen

CodeSmith

IgnyteDataLayerGen

NetGenerationCodeGen

Генератор кода OxyGen

.NetTiers

CodeThatBuilder

CslaGenerator

CodeBreeze

В качестве альтернативы следующие коды может сделать вашу жизнь более легкой.

У вас может быть общая базовая форма для таких объектов:

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);
        }            
    }

Тогда все ваши формы будут иметь одинаковый общий вид:

alt text

3
ответ дан 5 December 2019 в 12:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: