Когда я запускаю форму без отправки информации, она правильно открывает представление списка с заголовками столбцов.
Однако когда я пытаюсь открыть ту же форму для обновления информации, представление списка теряет заголовки. несуществующий fcam и все остальное программирование поверх списка
нормальное открытие без отправки данных
Код:
public FrmMicroConfig()
{
InitializeComponent();
}
открытие с отправкой данных
public FrmMicroConfig(string device) : this()
{
Dispostivo dispositivo = Dispostivo.JsonDesserializar(device);
txtDevicename.Text = dispositivo.Nome;
txtDeviceIp.Text = dispositivo.IP;
txtDeviceLocal.Text = dispositivo.Local;
LstdeviceVariables.Columns.Add("Nome");
LstdeviceVariables.Columns.Add("Id");
LstdeviceVariables.Columns.Add("StartBit");
LstdeviceVariables.Columns.Add("Lenght");
LstdeviceVariables.Columns.Add("Factor");
LstdeviceVariables.Columns.Add("Offset");
foreach (var Variable in dispositivo.Variables)
{
ListViewItem lvi = new ListViewItem(Variable.Nome);
lvi.SubItems.Add(Variable.Id.ToString());
lvi.SubItems.Add(Variable.Startbit.ToString());
lvi.SubItems.Add(Variable.Lenght.ToString());
lvi.SubItems.Add(Variable.Factor.ToString());
lvi.SubItems.Add(Variable.Offset.ToString());
LstdeviceVariables.Items.Add(lvi);
}
InitializeComponent();
}
Результатом этого являются эти два экрана
Нормальное открытие:
введите сюда описание изображения
Неправильное открытие:
введите сюда описание изображения
не могу определить откуда ошибка Я уже пытался добавить заголовки позже, но ничего и даже без добавления элементов в список результат тот же просмотр списка работает неправильно
Есть идеи, как генерируется эта ошибка? Может быть, какая-то неправильная конфигурация класса или тип объекта?
Кроме того, вам необходимо переместить часть создания заголовков столбцов в вектор по умолчанию. Сразу после InitializeComponent();
. Или просто добавьте их дизайнером и забудьте об этой части. Просто добавьте элементы в код.
В конструкторе вашей формы InitializeComponent() должен быть либо первым, либо одним из первых элементов (на самом деле, я удивлен, что он не вызывает исключения!). Это гарантирует, что все элементы управления настроены в соответствии с вашим дизайнером.
Если вы вызовете InitializeComponent() позже, согласно вашему текущему коду, он перезапишет все, что вы настроили до этого.
public FrmMicroConfig(string device) : this() {
//Call InitializeComponent first.
InitializeComponent();
Dispostivo dispositivo = Dispostivo.JsonDesserializar(device);
//Now the rest of your code.
txtDevicename.Text = dispositivo.Nome;
txtDeviceIp.Text = dispositivo.IP;
txtDeviceLocal.Text = dispositivo.Local;
LstdeviceVariables.Columns.Add("Nome");
LstdeviceVariables.Columns.Add("Id");
LstdeviceVariables.Columns.Add("StartBit");
LstdeviceVariables.Columns.Add("Lenght");
LstdeviceVariables.Columns.Add("Factor");
LstdeviceVariables.Columns.Add("Offset");
foreach (var Variable in dispositivo.Variables)
{
ListViewItem lvi = new ListViewItem(Variable.Nome);
lvi.SubItems.Add(Variable.Id.ToString());
lvi.SubItems.Add(Variable.Startbit.ToString());
lvi.SubItems.Add(Variable.Lenght.ToString());
lvi.SubItems.Add(Variable.Factor.ToString());
lvi.SubItems.Add(Variable.Offset.ToString());
LstdeviceVariables.Items.Add(lvi);
}
}
Но хорошей практикой является также размещение InitializeComponent
в конструкторе по умолчанию, чтобы избежать проблем. А если вы не хотите, чтобы его вызывали, установите для него статус «частный». Так что у тебя есть:
public FrmMicroConfig(string device) : this() {
//your code
}
private FrmMicroConfig()
{
InitializeComponent();
}
Когда я запускаю конструктор раньше, никакие данные не загружаются (текстовые поля содержат значения), в этой ситуации никакая информация не загружается, и заголовки столбцов также не загружаются.
Да, я не заметил, что это не конструктор по умолчанию! Забавно, в тот же день я взял чужой код именно для этой проблемы!!
Вектор по умолчанию должен быть public
. Это конструктор, который вызывается при создании формы (причина, по которой там должен быть InitializeComponent()
). Если только это не форма, для которой не требуется конструктор (т. е. только встроенный пользовательский код).
В методе InitializeComponent
создаются и настраиваются все ваши элементы управления. Если вы поместите код, ссылающийся на ваши элементы управления, в конструктор перед вызовом этого метода, будет выброшен NullReferenceException
, а остальная часть конструктора не будет выполнена. Любой дополнительный код необходимо ввести ПОСЛЕ звонка на InitializeComponent
.
Когда я запускаю конструктор раньше, никакие данные не загружаются (текстовые поля содержат значения), в этой ситуации никакая информация не загружается, и заголовки столбцов также не загружаются.
Мне удалось заставить это работать таким образом
Удалить InitializeComponent()
public FrmMicroConfig (строковое устройство): this() {
Dispostivo dispositivo = Dispostivo.JsonDesserializar(device);
txtDevicename.Text = dispositivo.Nome;
txtDeviceIp.Text = dispositivo.IP;
txtDeviceLocal.Text = dispositivo.Local;
foreach (var Variable in dispositivo.Variables)
{
ListViewItem lvi = new ListViewItem(Variable.Nome);
lvi.SubItems.Add(Variable.Id.ToString());
lvi.SubItems.Add(Variable.Startbit.ToString());
lvi.SubItems.Add(Variable.Lenght.ToString());
lvi.SubItems.Add(Variable.Factor.ToString());
lvi.SubItems.Add(Variable.Offset.ToString());
LstdeviceVariables.Items.Add(lvi);
}
}
Я просто оставил «:this()» в начале кода.
Спасибо за ответ @dr.null
Удалите метод
InitializeComponent();
из перегрузки конструктора! Вы воссоздаете все таким образом. Ваш параметризованный вектор уже вызывает вектор по умолчанию (: this()
), который вызывает методInitializeComponent();
. Вы должны вызывать этот метод только один раз, и в форме он должен вызываться из вектора по умолчанию.