diablo22 Ответов: 2

Vb.net формы элементов управления и панелей


Здравствуйте, может кто-нибудь сказать мне, почему у меня возникла эта проблема.
Я пытаюсь создать 1 основную форму, и внутри у меня есть панель, которая будет загружать другую форму внутри нее. И у меня есть проблема, когда мой запрос запускается внутри базы данных, он заполнен пустыми полями, похоже, он не читает то, что есть внутри текстовых полей, и флажки они проверяются, если они есть "1"

Вот моя основная форма вызывающая внутри панели другую форму :
Dim form2 As UsersAddCP = New UsersAddCP()
        form2.TopLevel = False
        form2.TopMost = True
        Dim form1 As AdminMenu = CType(Application.OpenForms("AdminMenu"), AdminMenu)
        Dim panel1 As Panel = CType(form1.Controls("panel1"), Panel)
        panel1.Controls.Clear()
        panel1.Controls.Add(form2)
        form2.Show()

А вот мой модуль запроса для вставки информации.
 Public Sub RegisterUser()
        Try
            With cmd
                .Connection = conn
                .CommandText = "INSERT INTO users (uname,upassword,ucode,ucreate,utools,usearch) VALUES (@user,@pass,@ucd,@crt,@uto,@usrh)"
                .Parameters.AddWithValue("@user", UsersAddCP.txtUsername.Text)
                .Parameters.AddWithValue("@pass", UsersAddCP.txtPassword.Text)
                .Parameters.AddWithValue("@ucd", UsersAddCP.AdminCheck.Checked)
                .Parameters.AddWithValue("@crt", UsersAddCP.CreateCheck.Checked)
                .Parameters.AddWithValue("@uto", UsersAddCP.ToolsCheck.Checked)
                .Parameters.AddWithValue("@usrh", UsersAddCP.SearchCheck.Checked)
                .ExecuteNonQuery()
                .Parameters.Clear()
                .CommandText = "INSERT INTO personal (pacc,pName,pEmail,pYazaki,pPhone,pPosition) VALUES (@user,@name,@email,@yazaki,@phone,@position)"
                .Parameters.AddWithValue("@user", UsersAddCP.txtUsername.Text)
                .Parameters.AddWithValue("@name", UsersAddCP.txtName.Text)
                .Parameters.AddWithValue("@email", UsersAddCP.txtEmail.Text)
                .Parameters.AddWithValue("@yazaki", UsersAddCP.txtyazaki.Text)
                .Parameters.AddWithValue("@phone", UsersAddCP.txtPhone.Text)
                .Parameters.AddWithValue("@position", UsersAddCP.txtPossition.Text)
                Result = .ExecuteNonQuery
            End With
        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            If Result > 0 Then
                MessageBox.Show("Sign Up Successful", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MsgBox("Failed to register user!")
            End If
            cmd.Dispose()
            If conn IsNot Nothing Then
                conn.Close()
            End If
        End Try
    End Sub
End Module


Проблема возникает только тогда, когда я использую для загрузки форму внутри панели.
Если я использую обычную загрузку форм и заполняю поля, записи считываются и вставляются в поля базы данных, но когда я использую панель в базе данных, создаются пустые поля..Странно, может быть, кто-то может помочь мне решить эту проблему?

Что я уже пробовал:

Нормальная загрузка формы и вставка записей - работает
Загрузить в панель другую форму и вставить записи - дать пустые поля в базе данных

Maciej Los

Я не вижу той части кода, которая отвечает за чтение данных...

Ralf Meier

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

diablo22

Не могли бы вы дать более подробную информацию или пример того, что вы имеете в виду, извините, что я не смог уловить вашу точку зрения.
Заранее спасибо.

Richard Deeming

NB: Похоже, что вы храните пароли в обычном тексте. Не делай этого.

Безопасная Аутентификация Паролем Объясняется Просто[^]
Соленое хэширование паролей - делаем это правильно[^]

diablo22

насколько я читал, лучший вариант для anti-inject-это использовать параметры, как я делаю в своей функции, я не знаю, правда ли это до сих пор или как проверить, чтобы сделать sql inject, чтобы увидеть, будет ли он работать

diablo22

как вы упомянули, я осмотрел свой код, и Вы были правы, что я оставил пустые места для sql-инъекции, я просто тестирую его сам, поэтому одну идею, которую вы упомянули, я приведу в пример, чтобы другие люди тоже могли найти ее полезной.
Не так и легко запросов SQL инъекции :
.Свойства commandtext = "выбрать * из пользователей, где команде uname = '" &усилителя; формы.txtUsername.Текст & "'"
должно стать вот так:
.Свойства commandtext = "выбрать * из пользователей, где команде uname = @имя пользователя"
.Параметры.AddWithValue("@UserName", theForm.txtUsername.Текст)

2 Ответов

Рейтинг:
13

Richard Deeming

Цитата:
Dim form2 As UsersAddCP = New UsersAddCP()
...
.Parameters.AddWithValue("@user", UsersAddCP.txtUsername.Text)
Вы столкнулись с одним из ужасных аспектов VB.NET, который был разработан для обратной совместимости с VB6.

Почему существует экземпляр по умолчанию для каждой формы в VB?Net, но не в C#? - переполнение стека[^]

UsersAddCP.txtUsername относится к управлению ВКЛ. скрытый экземпляр по умолчанию из UsersAddCP форма. Но вы не используете этот экземпляр по умолчанию; вы создаете конкретный экземпляр формы и отображаете его. Таким образом, все элементы управления в экземпляре по умолчанию будут пустыми.

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


diablo22

поэтому мне нужно что-то в form2, когда вы вводите поля и нажимаете кнопку, чтобы использовать в регистре некоторые общедоступные определения, чтобы получить доступ к информации form2, можете ли вы дать мне небольшую помощь или пример того, что я должен сделать, чтобы лучше сделать этот материал работает? даже если его другой метод, чтобы сделать регистр работает с опцией панели. Спасибо

Richard Deeming

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

Dim form1 As AdminMenu = DirectCast(Application.OpenForms("AdminMenu"), AdminMenu)
Dim panel1 As Panel = DirectCast(form1.Controls("panel1"), Panel)
If panel1.Controls.Count <> 0 Then
    Dim form2 As UsersAddCP = TryCast(panel1.Controls(0), UsersAddCP)
    If form2 IsNot Nothing Then
        RegisterUser(form2)
    End If
End If
Public Sub RegisterUser(ByVal theForm As UsersAddCP)
    ...
        ' Instead of UsersAddCP.Control.Text, use theForm.Control.Text:
        .Parameters.AddWithValue("@user", theForm.txtUsername.Text)
    ...
End Sub

diablo22

когда я делаю это, чтобы изменить его на такой:
Public Sub RegisterUser(ByVal theForm As UsersAddCP)
...
- Вместо UsersAddCP.Control.Текст, используйте форму.Control.Text:
.Параметры.AddWithValue ("@user", theForm.txtUsername.Текст)
...
Конец Подводной Лодки

я получил подчеркивание txtUsername не является членом или UserAddCP

Richard Deeming

Это не имеет смысла - если он доступен через экземпляр формы по умолчанию (UsersAddCP.txtUsername), то он должен быть доступен через конкретный экземпляр (theForm.txtUsername).

NB: Версия RegisterUser Я опубликовал сокращенный пример, просто чтобы продемонстрировать, что вы должны заменить экземпляр формы по умолчанию экземпляром, переданным в качестве параметра. Он не был предназначен для замены всего тела метода. :)

diablo22

я нашел в этом проблему, просто visual studio несколько раз выдает ошибки и нуждается в перезапуске, чтобы функционально исправить их.
Но твоя идея была perfect..to дайте в функции Public Sub RegisterUser(ByVal theForm As UsersAddCP) строку для использования
Затем в кнопке click я просто использую RegisterUser(me) ,потому что я не могу использовать то же имя, что и я, тогда функция называется correct и читает correct theForm.txtUsername.Текст)
Perfect сделает еще несколько тестов, чтобы просмотреть его, и сообщит об этом через несколько минут

diablo22

отлично теперь все в порядке я обнаружил что не могу использовать здесь то же самое для звонков Боут
.Свойства commandtext = "вставить в пользователи (команде uname,upassword,ucode,ucreate,utools,usearch) значения (@пользователь,@пасс,@СКД,@ЭЛТ,@УТО,@usrh)"
.Параметры.AddWithValue ("@user", theForm.txtUsername.Текст)
.Параметры.AddWithValue ("@pass", theForm.txtPassword.Text)
.Параметры.AddWithValue ("@ucd", theForm.AdminCheck.Проверен)
.Параметры.AddWithValue ("@crt", theForm.CreateCheck.Проверен)
.Параметры.AddWithValue("@uto", форма.Проверка инструментов.Проверен)
.Параметры.AddWithValue("@usrh", theForm.SearchCheck.Проверен)
.Метод executenonquery()
.Параметры.Четкий()
.Свойства commandtext = "добавить в личное (ПАКК,изъятия,pEmail,pYazaki,pPhone,расположен) значения (@userx,@имя,@почта,@Язаки,@телефон,@положение)"
.Параметры.AddWithValue("@userx", theForm.txtUsername.Текст)
потому что он дает ошибку параметр уже определен, поэтому я изменил его на -> userx и все нормально. Спасибо

Richard Deeming

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

Использование Оператора (Visual Basic) | Microsoft Docs[^]

Сохранение объектов базы данных, зависающих в полях, приведет к трудным для отслеживания ошибкам и, возможно, даже повреждению данных.

diablo22

правильно я это исправил и мне не нужно использовать метод блоков моя ошибка была в том, что я использовал одно и то же определение 2 раза и catch ex нашел его и заменил теперь работает как шарм создание аккаунтов без проблем. Если пользователь существует = извините , если не создадите его.

Рейтинг:
1

RickZeeland

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

Смотрите первый ответ OriginalGriff об использовании a элемент управления UserControl здесь: Как добавить форму в панель из другой формы[^]

Видеть: Создание простого пользовательского элемента управления с помощью Visual Basic[^]
Если вы предпочитаете видео, смотрите: Vb.Net Элемент Управления UserControl - Ютуб[^]

А вот пример обмена данными между несколькими формами с помощью модуля: Visual Basic (VB) делится глобальными переменными между несколькими формами с помощью модуля - YouTube[^]

Вот более сложный пример, который показывает, как отделить ваши данные от формы, используя PL (уровень презентации), BLL (уровень бизнес-логики) и DAL (уровень доступа к данным):
Построение N-уровневого приложения в VB.NET, в 8 шагов[^]


diablo22

Я хочу сделать вот что:
Новый проект>VB.net>Form1
В форме 1 я добавил панель 1
В form1 я добавил 1 кнопку для открытия form2 внутри Panel1 (которая в исходном Form1 называется AdminMenu)
Код выше для вызова form2 (который в исходном коде называется UsersAddCP)

Итак, что у меня есть в Form2 (UsersAddCP)
У меня есть 7 текстовых полей + 4 флажка + 1 кнопка для сохранения

Ладно, давайте начнем,
Когда я нажимаю в форме 1 кнопку для вызова формы 2 внутри панели 1, она работает нормально.
Но когда я пытаюсь написать в текстовых полях что-то и нажать на кнопку.
Кнопка вызывает функцию RegisterUser() и внутри базы данных создает новую запись, но с пустыми полями.
Хорошо, что я пытаюсь я пытаюсь поставить на Form2 все текстовые поля (Text = "some default text") и я запускаю программу и ничего не пишу в текстовые поля, потому что они теперь имеют значение по умолчанию text и нажимаю кнопку, чтобы создать в базе данных записи правильно.

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

RickZeeland

Не используйте форму в панели, это плохой дизайн !
См. обновленное решение для ссылки на "создание простого пользовательского элемента управления с помощью Visual Basic"

diablo22

нет никакого способа решить эту проблему, потому что я хочу сделать более эффективную программу, чтобы не отображать новые формы, а закрывать предыдущие и все такое, что-то вроде 1 основной формы и отображать функции из других форм заполнять информацию сохранять читать это невозможно?

RickZeeland

Я постараюсь найти для вас пример, но, пожалуйста, больше не помещайте формы в панели :)

RickZeeland

Не удалось найти хорошего VB.Чистый пример, но только простой, который показывает, как обмениваться данными между формами.

diablo22

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

diablo22

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