C #, как настроить свойство текстового поля в форме из другого класса? - PullRequest
4 голосов
/ 14 апреля 2011

Я до сих пор не могу понять, как получить доступ к элементам управления в форме из другого class.im, нового для c #, поэтому мой метод "проб и ошибок" на самом деле не работает.

Может кто-нибудь дать мне простое руководство?

это мой фрагмент кода

Форма 1:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            print pr = new print();
            pr.p();

        }

    }
}

Это печать класса:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication2
{
    class print 
    {
        public print()
        {

        }

        public void p()
        {
            Form1 f = new Form1();
            f.textBox1.Text = "change text";

        }     

    }

}

, как вы можете видеть, я пытаюсьизмените свойство textBox1 в классе print.but, но когда я его скомпилирую, я получаю исключение System.StackOverflowException!

я сейчас расстроен, потому что я не могу получить к нему доступ из другого класса.

может кто угоднодайте мне шаг за шагом, как вызвать его из класса печати? Я пробовал много шагов из Интернета, но я просто не могу его получить.

Кстати, я сделал модификатор для текстового поля общедоступным.

Ответы [ 8 ]

5 голосов
/ 14 апреля 2011

Проблема в том, что метод print.p создает новую форму, а конструктор формы снова вызывает метод print.p.Затем создается другая новая форма, конструктор которой снова вызывает метод print.p, повторяя цикл снова и снова.Вот откуда приходит StackOverflowException.

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

Быстрое и грязное исправление требует, чтобы вы нашли способ получить ссылку на экземпляр вашего класса формы в print.p метод.Только так вы сможете вызывать методы для этого объекта, вместо создания нового объекта этого класса.Один из способов - передать ссылку на метод в качестве параметра:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        print pr = new print();
        pr.p(this);
    }
}

class print 
{
    public print()
    {

    }

    public void p(Form frm)
    {
        frm.textBox1.Text = "change text";
    }     
}

Кроме того, в качестве несколько неуместной стилистической заметки вы должны знать, что почти все руководящие принципы / соглашения по кодированию для C # (и.NET платформа) требуют, чтобы имена классов и методов были PascalCased, а не camelCased.Итак, ваш print класс должен на самом деле называться Print.

1 голос
/ 14 апреля 2011

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

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        print pr = new print();
        pr.p(this);
    }
}

public class print 
{
    public print() {}

    public void p(Form1 f)
    {
        f.textBox1.Text = "change text";
    }     
}
1 голос
/ 14 апреля 2011

Вы получаете StackOverFlowException, потому что вы создаете новый экземпляр из print в Form1, используя этот код:

print pr = new print();

Затем в конструкторе в print вы создаете новый экземпляр Form1, например:

Form1 f = new Form1();

, который создает новый экземпляр print, который создает новый экземпляр Form1, который создает новый экземпляр print, который создает новый экземпляр Form1, который ...

Вы создали бесконечный цикл, который убивает стек.

1 голос
/ 14 апреля 2011

Код, который у вас есть, проблематичен по другим причинам (@CodyGray объясняет, почему, именно поэтому вы получаете StackOverflowException), но в целом вы можете использовать свойство, чтобы разрешить доступ, не раскрывая фактическую TextBox контролировать себя;см. эту страницу MSDN для подробностей, но например:

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
        }

        public string FormText
        {
            get { return textBox1.Text; }
            set { textBox1.Text = value; }
        }
    }
}

Затем, чтобы использовать это свойство:

public void p()
{
    Form1 f = new Form1();
    f.FormText = "change text";
}  

РЕДАКТИРОВАТЬ:

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

Давайте представим, что цель состоит в том, что вы хотите set текст в p, мы просто вернем то, что нам нужно:

public string p()
{
    return "change text";
}  

Так что:

myFormReferenceSomewhereNotInPrintClass.FormText = myPrintClassInstance.p();

Или вы хотите get, или использовать текст в p:

public void p(string text)
{
    //do your thing with the text
}

Так что:

myPrintClassInstance.p(myFormReferenceSomewhereNotInPrintClass.FormText);
1 голос
/ 14 апреля 2011

Самый простой способ - просто передать ссылку на новую форму.

print pr = new print(textbox);

public print(Textbox textbox)
{
   //do something with textbox.

}

Однако существует ряд шаблонов проектирования, которые могут помочь с этим, например, MVP или MVVM.Тем не менее, они могут быть немного продвинуты для вашего текущего уровня.Если это всего лишь простой небольшой проект, то приведенный выше код подойдет.

0 голосов
/ 04 августа 2012
public static MainForm frm; 

public MainForm(){ 
    frm = this; 
    Yes() 
} 

public Yes(){ 
    frm.textbox1.text = ":D"; 
}
0 голосов
/ 14 апреля 2011
public Form1()
        {
            InitializeComponent();
            print pr = new print(this);
            pr.p();

        }

и в классе печати используйте это, чтобы получить форму

{
Form fpassed;

           public print(Form f)
            {
               fpassed = f;

            }

            public void p(Form f)
            {

                f.textBox1.Text = "change text";

            }     
}

может вызвать его по p (fpassed);

0 голосов
/ 14 апреля 2011

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

лучший способ сделать это:

Form1:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            print pr = new print();
            textBox1.Text = pr.p();
        }

    }
}

класс печати:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication2
{
    class print 
    {
        public print()
        {

        }

        public string p()
        {
            return "change text";
        }     

    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...