Как перенести текст из таблицы данных в одной форме в личное текстовое поле в другой форме - PullRequest
0 голосов
/ 26 ноября 2018

[Summary] У меня есть Invoice form с несколькими приватными TextBoxes в моей программе на C #.Когда пользователь изменяет текст этих текстовых полей, появляется search form.Я хотел бы передать некоторые значения из моего dataGridView (который связан с моей базой данных) в search form в эти текстовые поля в Invoice form (когда я нажимаю, например, Enter).

[Описание] Вмоя форма счета-фактуры. У меня есть текстовое поле с кодом товара и текстовое поле с названием товара.Когда пользователь изменяет текст этих текстовых полей, появляется форма поиска, и введенный текст будет перенесен в текстовое поле формы поиска.Форма поиска имеет только текстовое поле и сетку данных.Когда что-то вводится в текстовое поле формы поиска, сетка данных будет искать и показывать результаты в сетке данных.Представление таблицы данных содержит относительные столбцы как текстовые поля формы «Счет-фактура».Теперь я хочу сделать это: когда я вхожу в поисковую форму, информация о текущей строке сетки данных передается в соответствующие текстовые поля в форме счета.Столбец кода товара в текстовое поле кода товара и столбец названия товара в текстовое поле имени товара.

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

if (e.KeyCode == Keys.Enter)
{
    SqlCommand sqlcmd = new SqlCommand("SELECT ID FROM X WHERE ID=" +
                        dataGridView1.CurrentRow.Cells[0].Value + "", sqlcon);
    SqlDataReader sqldr = sqlcmd.ExecuteReader();
    while (sqldr.Read())
    {
        InvoiceForm.CodeTextBox = sqldr[codecolumn].Tostring
        InvoiceForm.NameTextBox = sqldr[Namecolumn].Tostring
        InvoiceForm.BlahTextBox = sqldr[Blahcolumn].Tostring                               
    }
}

Я пробовал приведенный выше код, но он говорит:

codeTextBox является закрытым ... не может сделать это из-за уровня защиты ...

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

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Без реализации интерфейса есть два простых метода для ссылки на существующий класс Form из другого класса.

Передача ссылки на класс вызывающего (this) в конструктор вызываемого объекта.:

Form2 form2 = new Form2(this);
form2.Show();

Использование свойства Владелец вызываемого абонента (Form2).Владелец устанавливается с помощью методов Show (Владелец) или ShowDialog (Владелец) .this является экземпляром вызывающего:

Form2 form2 = new Form2();
form2.Show(this);

Вы также можете иметь открытое свойство в вызываемом объекте (Form2), используемое для установки текущего вызывающего (this):

Form2 form2 = new Form2();
form2.MyCaller = this;
form2.Show();

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

Здесь я использую свойство Owner для доступа к экземпляру класса Form, в котором был создан ваш Search Форма класса.В этом примере используется открытый метод класса вызывающей стороны (ваш InvoiceForm), который вызываемый абонент (ваша форма Search) использует для передачи значений, выбранных пользователем.
Использование Form.Show(this) также подразумевает, что показанная Форма будет в виде (не путать со свойством Parent) с формой, которая показала ее и останется поверх нее.
Вы также можете использовать метод ShowDialog(this), если он предпочтителен в вашем случае.В этом случае форма будет отображаться как модальное диалоговое окно.

Я делаю два примера, используя этот открытый метод:

  1. Открытый метод с классомпараметр, который содержит все значения, которые можно установить в элементах управления InvoiceForm.Вероятно, это предпочтительный метод для передачи этих значений, поскольку его легче расширять и повторно использовать в различных контекстах.
  2. Открытый метод со строковыми параметрами, соответствующими значениям TextBoxes для установки

Открытый метод с параметром класса :
Обратите внимание, что this.Owner is InvoiceForm frm используется для идентификации текущего Owner.
Класс UpdateMyControls контейнер , используемый для передачи определенных значений.SearchForm мог бы действовать по-другому, если владелец был другим.
Это несколько упрощено, но вы можете использовать этот выбор, чтобы повторно использовать SearchForm с разными абонентами, получая разные результаты для каждого Owner.

Примечание : класс, используемый для передачи значений / ссылок, может передаваться в конструкторе SearchForm, возможно, с использованием известного контракта (интерфейса), который определяетценности и их типы.Слишком широк, чтобы описывать здесь, но вы должны рассмотреть эту возможность.

public partial class InvoiceForm : Form
{
    public class UpdateMyControls 
    {
        public string CodeText { get; set; }
        public string NameText { get; set; }
        public string BlahText { get; set; }
    }

    private void btnSearch_Click(object sender, EventArgs e)
    {
        SearchForm searcher = new SearchForm();
        searcher.Show(this);
    }

    public void UpdateControls(UpdateMyControls allValues)
    {
        this.CodeTextBox.Text = allValues.CodeText;
        this.NameTextBox.Text = allValues.NameText;
        this.BlahTextBox.Text = allValues.BlahText;
    }
}

public partial class SearchForm : Form
{
    private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Enter)
        {
            if (this.Owner is InvoiceForm frm)
            {
                InvoiceForm.UpdateMyControls updateClass = new InvoiceForm.UpdateMyControls();

                updateClass.CodeText = sqldr[codecolumn].ToString();
                updateClass.NameText = sqldr[Namecolumn].ToString();
                updateClass.BlahText = sqldr[Blahcolumn].ToString();
                frm.UpdateControls(updateClass);
                this.Close();
            }
        }
    }
}

Открытый метод с несколькими параметрами :

public partial class InvoiceForm : Form
{
    private void btnSearch_Click(object sender, EventArgs e)
    {
        SearchForm searcher = new SearchForm();
        searcher.Show(this);
    }

    public void UpdateControls(string Code, string Name, string Blah)
    {
        this.CodeTextBox.Text = Code;
        this.NameTextBox.Text = Name;
        this.BlahTextBox.Text = Blah;
    }
}

public partial class SearchForm : Form
{
    private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Enter)
        {
            string CodeValue = sqldr[codecolumn].ToString()
            string NameValue = sqldr[Namecolumn].Tostring
            string BlahValue = sqldr[Blahcolumn].Tostring 

            if (this.Owner is InvoiceForm frm)
            {
                frm.UpdateControls(CodeValue, NameValue, BlahValue);
                this.Close();
            }
        }
    }
}
0 голосов
/ 26 ноября 2018

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

В простых случаях, когда свойство по существу не зависит, яобычно добавляет в класс свойства, которые скрывали бы детали реализации от вызывающей стороны.

public string Code
{
    get { return CodeTextBox.Text; }
    set { CodeTextBox.Text = value; }
}

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

public void SetData(string code, string name, string blah)
{
    CodeTextBox.Text = code;
    NameTextBox.Text = name;
    BlahTextBox.Text = blah;
}

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

Но если вы перезагрузите данные из базы данных, то вы можете рассмотреть возможность перемещения кода в InvoiceForm и иметьфункция похожа на:

void LoadFromDatabase(int itemId)
{
    var sqlcmd = new SqlCommand("SELECT ID FROM X WHERE ID=" +
                        itemId.ToString(), sqlcon);
    var sqldr = sqlcmd.ExecuteReader();
    if (sqldr.Read())
    {
        InvoiceForm.CodeTextBox = sqldr[codecolumn].Tostring();
        InvoiceForm.NameTextBox = sqldr[Namecolumn].Tostring();
        InvoiceForm.BlahTextBox = sqldr[Blahcolumn].Tostring();                               
    }
}

Кстати, обратите внимание, что я должен заменить цикл while условием if.Очевидно, что запрос должен возвращать один элемент, так как в противном случае это будет означать, что база данных содержит повторяющиеся значения.Если данные являются поддельными, почему предпочли последний возвращенный элемент первому?

Я также добавил недостающие (); после ToString вызовов.

...