переменная класса сбрасывается при вызове методов в нескольких формах - PullRequest
2 голосов
/ 03 ноября 2011

Обновлено для отражения в моем собственном источнике

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

При работе с переменными get / set в классе, лучшая практика должна выглядеть примерно так:

JobMove.cs

public class JobMove
{
    private List<string> jobNames { get; set; }
    public string Scanner;

    public JobMove()
    {
        this.Scanner = Properties.Settings.Default.Scanner;
    }

    public void ListSelected(ListBox lbx)
    {
        foreach (string jName in this.jobNames)
        {
            lbx.Items.Add(jName);
        }
    }

    public static List<string> GetCheckedJobs(ListView lw)
    {
        int countChecked = lw.CheckedItems.Count;
        int itemCount = 0;
        List<string> jList = new List<string>();

        foreach (ListViewItem item in lw.CheckedItems)
        {
            JobInfo jobInfo = Job.Find(Convert.ToInt32(lw.Items[item.Index].SubItems[1].Text));
            jList.Add(jobInfo.Name);
            itemCount++;
        }
        return jList;
    }
}

Моя проблема заключается в том, что когда я объединяю это с моими формами и вызываю это, тогда я пытаюсь сделать что-то вроде этого:

MyForm1.cs

public partial class MyForm1 : Form
{
    private void btnMoveJobs_Click(object sender, EventArgs e)
    {
        Properties.Settings.Default.Scanner = cbxScanners.SelectedItem.ToString();

        JobMove moveJobs = new JobMove();

        frmMoveJobs FrmMoveJobs = new frmMoveJobs();
        FrmMoveJobs.ShowDialog();
    }
}

MyForm2.cs

public partial class frmMoveJobs : Form
{
    public frmMoveJobs()
    {
        InitializeComponent();

        JobMove moveJobs = new JobMove();
        lblFrom.Text = moveJobs.Scanner;
        moveJobs.ListSelected(lbxJobsToMove);

        cbxMjScanners.DataSource = System.Enum.GetValues(typeof(Scanners));
    }
}

Но когда я вызываю MyClass in MyForm2 , и я хочу вызвать DoSomethingElse методтогда myString будет сброшено до значения null .И это имеет смысл для меня, но как мне обойти это?

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

Мне может просто понадобиться точка в правильном направлении вправочто делать в этой ситуации.

Ответы [ 6 ]

4 голосов
/ 03 ноября 2011

Если вы делаете MyClass myClass = new MyClass();, тогда действительно - значения независимы и не связаны. Если вы хотите поделиться экземпляром MyClass, то передайте экземпляр MyClass между формами. Может быть:

using(var form2 = new Form2()) {
    form2.SensibleName = existingMyClassInstance;
    form2.ShowDialog();
}

(обратите внимание на using выше; при использовании ShowDialog() ваша задача - убедиться, что форма удалена; она удаляется автоматически только при использовании Show())

3 голосов
/ 03 ноября 2011

Во-первых, это свойства, а не переменные (переменные являются основным источником данных).

Во-вторых, весь смысл аксессоров get / set состоит в том, что вы можете получить и установить значение без использования вспомогательных методов.

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

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

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

1 голос
/ 03 ноября 2011

Несколько вариантов:

  1. Передать экземпляр MyClass в конструктор формы 2.

  2. Сделать MyClass статическимForm1

  3. Сделать MyClass статичным (не рекомендуется) .

0 голосов
/ 03 ноября 2011

Простое решение:

private static string myString { get; set; } 

Почему: потому что вы инициализируете класс снова при инициализации Form2, и он создаст новый класс.С помощью ключевого слова «static» вы создаете свойство, которое одинаково во всех экземплярах этого класса.

НО : пожалуйста, прочитайте несколько книг, прежде чем продолжить, это будет решением этой проблемы, но источник многих других.Попробуйте сначала понять C # и Forms, а затем (или вместе с чтением / обучением) начать кодирование!

0 голосов
/ 03 ноября 2011

это потому, что у каждой вашей формы есть новый объект "MyClass".

Чтобы достичь того, что вы хотите сделать, используйте статическое свойство ... оно не будет инициализировано и возвращает одинаковое значение для каждого объекта MyClass это выглядит так

public class MyClass {
   public static string myString { get; set; }

   public void ChangeMyString(string newString)
   {
       myString = newString;
   }

   public void DoSomethingElse()
   {
       MessageBox.Show(myString);
   }

}
0 голосов
/ 03 ноября 2011

Если вы хотите использовать экземпляр MyClass, созданный в MyForm1 внутри MyForm2, вам необходимо предоставить его MyForm2.

Примерно так будет работать:

public partial class MyForm2 : Form
{
    public MyForm2(MyClass given)
    {
        InitializeComponent();

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