Как обновить sh список поля со списком, читаемый из текстового файла - PullRequest
0 голосов
/ 08 мая 2020

Как мне получить самую свежую информацию из файла .txt, связанного с моим полем со списком? У меня есть форма, которая записывает в файл .txt, и другая форма (поле со списком), которая читает из этого файла .txt. Но форма, которая читает, не получает последние входные данные в файл .txt, если я не закрою форму и не открою ее повторно. Как я могу указать в поле со списком обновить sh файл .txt? Screen Shot

    Private Sub RadioButton1_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton1.CheckedChanged
    If RadioButton1.Checked = True Then
        Dim FILE_NAME As String = "C:\Users\ladam\Desktop\Fiber Type.txt"
        ComboBox1.Items.Clear()


        If IO.File.Exists(FILE_NAME) Then
            Using sr As New IO.StreamReader(FILE_NAME)
                While Not sr.EndOfStream

                    ComboBox1.Items.Add(sr.ReadLine)
                End While
            End Using
        Else

            MsgBox("Oooops, File not found !!!")
        End If
        Label8.Text = "fl oz"
        Label23.Text = "(sq in)"
        Label24.Text = "(sq in)"

Ответы [ 3 ]

1 голос
/ 09 мая 2020

Переместите код, чтобы заполнить поле со списком в отдельный Sub. Затем он вызывается из события RadioButton1_CheckedChanged. Я немного изменил код, чтобы упростить его. .ReadAllLines возвращает массив строк в текстовом файле. Затем .AddRange добавляет массив в комбинацию.

Установите видимость Friend, чтобы его можно было вызывать из других форм.

Код формы 1

Private Sub RadioButton1_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton1.CheckedChanged
    If RadioButton1.Checked = True Then
        FillCombo()
    End If
End Sub
Friend Sub FillCombo()
    Dim FILE_NAME As String = "C:\Users\ladam\Desktop\Fiber Type.txt"
    ComboBox1.Items.Clear()
    If File.Exists(FILE_NAME) Then
        Dim lines = File.ReadAllLines(FILE_NAME)
        ComboBox1.Items.AddRange(lines)
    Else
        MsgBox("Oooops, File not found !!!")
    End If
End Sub

Form2

Private Sub WriteToFile()
    'Code that writes to text file
    Form1.FillCombo()
End Sub

Это будет работать, если вы используете экземпляры Forms по умолчанию. Если вы создаете свои собственные экземпляры (не по умолчанию) Form2 потребуется ссылка на Form1.

Form1

Private Sub OpenForm2()
    Dim frm As New Form2
    frm.Show()
    frm.frm1 = Me
End Sub

Form2

Friend frm1 As Form1

Private Sub WriteToFile()
    'Code that writes to text file
    frm1.FillCombo()
End Sub
1 голос
/ 09 мая 2020

Осмелюсь сказать, что ваша жизнь была бы намного проще, если бы вы использовали DataSet и кучу таблиц данных и привязали к ним все эти комбинации:

Я бы сделал следующее. Шаги, которые я описываю здесь, должны занять около 5 минут, с дополнительной минутой для репликации различных фрагментов кода:

  • Щелкните правой кнопкой мыши свой проект в обозревателе решений
  • Выберите «Добавить новый». ...
  • Выберите DataSet (в разделе «Данные») выберите имя
  • Если он не открывается автоматически, дважды щелкните его. Вы видите пустую поверхность конструктора
  • Щелкните правой кнопкой мыши поверхность, Добавить новую .. Таблица данных
  • Назовите ее Fiber
  • Щелкните правой кнопкой мыши, Добавить столбец .., Назовите это FiberThickness, используйте сетку свойств, чтобы присвоить ему подходящий тип данных (double?)
  • Добавьте столбец для FiberWeight
  • Добавьте еще datatable и столбцы для Veil (вы можете видеть, что это начинает выглядеть как мини-база данных)
  • Продолжайте добавлять данные, а затем столбцы для всех связанных свойств. Думаю, в конце у вас будет 7 таблиц данных, и все, кроме последнего, будут иметь 2 столбца
  • Сохраните дизайн набора данных

  • Откройте конструктор для БД форма (без красной и синей кнопок)

  • Откройте окно «Источники данных» в меню «Вид» внутри «Другое» Windows
  • Разверните узел набора данных в окне «Источники данных» и перетащите его. таблиц на форму - будет создан grdiview вместе с набором данных (внизу на панели задач), источником привязки и навигатором привязки. Удалите навигатор, оставив только сетку, набор данных и источник привязки
  • Переименуйте набор данных в нижнем лотке; щелкните по нему и измените имя в сетке свойств, чтобы оно было подчеркнуто в начале. Это помогает, потому что в VB может возникнуть путаница, когда переменные имеют то же имя, что и тип объекта, и в этом случае конструктор формы сделал aa Dim thermoLamDataSet as New ThermoLamDataSet - два имени различаются только регистром, а VB не чувствителен к регистру, поэтому добавление ведущее подчеркивание помогает разделять вещи и знать, говорим ли мы о переменной или типе.
  • Повторите процесс добавления, а затем удаления. В конце у вас должен быть один набор данных и 7 источников привязки в лотке и 7 сеток в форме. Расположите сетки красиво, потому что они будут заменять ваши текстовые поля (ваша «база данных» будет знать о нескольких волокнах / вуалях и т. Д., Использование текстового поля для их отображения не идеально, потому что оно может отображать только одно - сетки работать лучше для этого, потому что ваши пользователи могут прокручивать вверх и вниз записи и редактировать их, удалять их и добавлять их)
  • Если вы абсолютно привержены идее сохранения текстовых полей , затем выполните этот процесс:
    • Разверните узел Fiber в окне источников данных, посмотрите, как теперь отображаются столбцы? Перетащите каждый столбец на форму. Снова вы получаете набор данных, привязку привязки, источник привязки в лотке, но на этот раз вы получаете текстовые поля
    • Эти только что удаленные текстовые поля уже подключены (привязаны) к столбцам таблицы набора данных. Удалите старые текстовые поля и аккуратно расположите новые. Также поместите навигатор привязки рядом с текстовыми полями на панели. Он будет использоваться для изменения того, что показывают текстовые поля, чтобы пользователь мог прокручивать записи в таблице волокон и редактировать существующие, удалять их, добавлять новые et c
  • Теперь мы иметь форму, которая позволяет редактировать каждую строку в таблицах данных набора данных. Добавьте кнопку «Сохранить» (и, возможно, кнопку «Сохранить как…» и кнопку «Загрузить») или введите код для сохранения набора данных при закрытии формы:
    Sub Form_Closing(...)
      _myDataSet.WriteXml(Path.ChangeExtension(Application.ExecutablePath, "xml"))

    End Sub

Эта одна строка кода сохранит весь набор данных и содержимое каждой таблицы по пути, который совпадает с именем exe, но с расширением xml. При желании вы можете указать другой номер c. Это не обязательно для работы коммуникации с другой формой, просто я думаю, вы не хотите, чтобы ваш пользователь вводил все эти данные каждый раз, когда они открывают приложение ...


Следующее, что нам нужно сделать, это сделать так, чтобы эта форма могла принимать набор данных в качестве параметра при его создании. Это сделано для того, чтобы основная форма могла быть ответственной за создание набора данных, но она будет передавать свой набор данных в эту форму для редактирования. Таким образом, две формы будут использовать одни и те же данные, и изменения, внесенные в эту форму, будут отражены в основной форме.

Поместите конструктор:

Public Sub New(ds as ThermoLamDataSet) 'whatever you called your dataset,

    _thermoLamDataSet = ds 'remember I said to change the name of the dataset in the tray at the bottom of the form - here _thermoLamDataSet is whateve the dataset in the tray is called

End Sub

В основной форме, когда пользователь нажимает кнопку (Изменить базу данных?), мы передадим экземпляр набора данных основной формы в эту форму при редактировании:

Public Sub EditDatabaseButton_Click(...) Handles EditDbButton.Click

  Call New EditorForm(Me._tlDS).Show() 'I'm going to rename the dataset on this form to _tlDS below

End Sub

Я решил вызвать набор данных в основной форме _tlDS чтобы подчеркнуть, что он отличается от формы в редакторе. Это тот же тип набора данных, так что набор из основной формы может быть передан в форму редактора, использован, и, таким образом, происходит обмен данными; обе формы используют один и тот же объект в памяти, просто у них разные имена для него. У них могут быть одинаковые имена, я просто не хотел, чтобы вы предполагали, что у них были с одинаковыми именами

Давайте настроим основную форму:

  • Откройте конструктор основной формы
  • Откройте окно источников данных
  • Разверните имя узла набора данных и узел Fiber. Используйте раскрывающийся список рядом со столбцом FiberThickness, чтобы перейти из текстового поля в поле со списком.
  • Перетащите комбо FiberThickness на форму, снова в лотке появится куча всякой всячины. Если появится навигатор, удалите его - он нам не нужен. Измените стиль раскрывающегося списка комбо на DropDownList
  • Переименуйте набор данных на панели в нижней части конструктора форм, измените его имя на _tlDS или подобное (я выбрал это, потому что предполагал, что имя ThermoLamDataSet было выбирается при добавлении файла набора данных в проект). Я обычно также переименовываю с помощью bindingsources et c, поэтому все они имеют начальный символ подчеркивания. Я делаю это своими кнопками и т.д. Повторите эти действия для других таблиц в окне источников данных (вуаль ...)

Теперь у вас есть основная форма с набором данных, набором источников привязки и некоторыми комбинированными списками, которые привязаны к таблицам набора данных. через эти источники привязки.

Вы можете запустить проект на этом этапе. Нажмите кнопку «Изменить базу данных».

  • Если вы сохранили текстовые поля, нажмите «+» в навигаторе привязок и запишите некоторые данные в текстовые поля, нажмите + еще раз, добавьте еще et c. Вы можете прокручивать добавленные записи.

  • Если вы выбрали использование сетки, это будет немного более интуитивно; напишите новые записи в нижнюю строку, отредактируйте записи редактирования, как если бы вы делали лист Excel

Закройте форму и посмотрите в основной форме комбинации; данные, которые вы отредактировали / добавили, есть, потому что обе формы работают с одним и тем же набором данных (созданным основной формой).

Остальные биты, которые нам нужно сделать:

  • Добавьте процедуру для загрузки набора данных при запуске приложения
  • Добавьте некоторые удобные свойства, чтобы получить текущую строку каждой таблицы данных. Я предполагаю, что вам это понадобится, потому что после того, как пользователь выберет толщину, вы захотите узнать связанный вес, чтобы вы могли что-то вычислить

Добавление процедуры для загрузки набора данных:

Public Sub MainFormLoad(...) Handles MainForm.Load


  Dim path = Path.ChangeExtension(Application.ExecutablePath, "xml")
  If File.Exists(path) Then _myDataSet.ReadXml()

End Sub

Да, только одна строка будет считывать набор данных из того же места, где его сохранила другая форма (если вы настроили этот logi c, сделайте то же самое здесь)

И удобное свойство, которое получает всю строку волокна, относящуюся к тому, что пользователь выбрал в комбинации волокон:

ReadOnly Property CurrentFiberRow() As ThermoLamDataSet.FiberRow
    Get
      'do'nt forget, I rename my BindingSources from the default fiberBindingSource to _fiberBindingSource
      If _fiberBindingSource.Current Is Nothing Then Return Nothing
      Return DirectCast(DirectCast(_fiberBindingSource.Current, DataRowView).Row, ThermoLamDataSet.FiberRow)
    End Get

Возможно, мы бы использовали это так (я не знаю, какой у вас cal c):

If CurrentFiberRow Is Nothing Then
  MessageBox.Show("Choose a fiber thickness first!")
  Return
End If

Dim result = CurrentFiberRow.Thickness * CurrentFiberRow.Weight * Convert.ToDouble(fiberAreaTextBox.Text)

...
0 голосов
/ 09 мая 2020

Расширение предложения BindingList . Я считаю, что форма справа, на которой размещен ComboBox, является основной формой, поэтому я отвечаю соответствующим образом.

MainForm


  • Объявить переменная класса типа BindingList.
  • Создать новый экземпляр в конструкторе и загрузить данные из текстового файла.
  • Привязать ComboBox.
  • Обработать событие FormClosing для обновления текстовый файл.
Imports System.ComponentModel
'...

Public Class MainForm

    Private ReadOnly FiberType As BindingList(Of String)

    Sub New()
        InitializeComponent()

        Dim filePath = "C:\Users\ladam\Desktop\Fiber Type.txt"

        FiberType = New BindingList(Of String)(File.ReadAllLines(filePath).ToList)
        FiberType.AllowNew = True
        ComboBox1.DataSource = FiberType
    End Sub

    Private Sub MainForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        File.WriteAllLines("C:\Users\ladam\Desktop\Fiber Type.txt", FiberType)
    End Sub

End Class

Форма ввода данных


  • Создайте параметризованный конструктор для передачи BindingList.
  • Добавьте новую запись в BindingList.
Imports System.ComponentModel

Public Class FrmFiberType

    Private ReadOnly FiberType As BindingList(Of String)

    Sub New()
        InitializeComponent()
    End Sub

    Sub New(data As BindingList(Of String))
        Me.New
        FiberType = data
    End Sub

    Private Sub BtnNewFiber_Click(sender As Object, e As EventArgs) Handles BtnNewFiber.Click
        FiberType.Add("The new type...")
    End Sub

End Class

Вот и все. Все, что вы добавляете в форму ввода данных, будет отображаться в ComboBox основной формы.

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

Module Module1
    Friend ReadOnly FiberType As BindingList(Of String)
End Module

Затем создайте экземпляр нового экземпляра в основной форме, как указано, или в событии MyApplication_Startup .

Также вы можете прочитать:

...