Сделать доступной переменную в нескольких формах в компактной структуре - PullRequest
2 голосов
/ 11 августа 2011

Я делаю приложение для устройства Windows CE 5.0 , которое запрашивает username в первой форме (при запуске приложения), а затем я получаю userId от таблица базы данных.

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

Пример:

public partial class Menu : Form
{
    int userId;
    public Menu(int userId)
    {
        InitializeComponent();
        this.userId = userId;
    }

    private void buttonDelivery_Click(object sender, EventArgs e)
    {
        Delivery delivery = new Delivery(userId);
        delivery.Show();
        this.Hide();
    }
    ...

Может быть, я должен использовать глобальную переменную, подобную этой?

public static class UserConfiguration
{
    public static int userId;
}

Разве это не плохая практика?

Наконец, имейте в виду, что компактный каркас не поддерживает app.config files

Ответы [ 3 ]

2 голосов
/ 11 августа 2011

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

Я был бы очень склонен иметь класс, который включал бы всю информацию пользователя (идентификатор, который выиспользуя, а затем, может быть, что-нибудь еще, например, имя и т. д.).Я создал бы экземпляр и заполнил бы эту информацию, когда будет отправлена ​​первая форма (логин), и я бы хранил ее в контейнере DI (я использую этот конкретно , но любой CF-поддерживающийКонтейнер будет работать).

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

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

2 голосов
/ 11 августа 2011

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

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

PS app.config неВ любом случае, это лучшее место для хранения определенных значений времени выполнения, поэтому не имеет значения, поддерживается ли CF в этом случае или нет; -)

1 голос
/ 10 сентября 2011

Если вы используете контроллер, он может содержать все необходимые переменные.Контроллер может иметь статическое свойство Instance, которое создает себя (см. Шаблон проектирования объекта Singleton).При разработке мобильных приложений это очень распространено, поскольку память часто является ограничением.Остальные методы являются открытыми членами (не статическими), поэтому вы можете получить к ним доступ следующим образом.Вы можете сделать их свойства или просто использовать публичный член.Даже с мобильными устройствами мы, как правило, не используем свойства, поскольку они просто добавляют ненужный пух и бокс / распаковку.

В одной форме вы можете использовать:

MainController.Instance.loginID = "me123";

, в другой вы можете использовать

MessageBox.Show("my loginID is: " + MainController.Instance.loginID);

Вы также можете добавить методы, такие как:

MainController.Instance.ClearSession();

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

MainController.Instance.ShowLoginForm();

код MainController в начале должен выглядеть примерно так:

public class MainController : IDisposable {
//all forms we are controlling
LoginForm _loginForm = null;

//all public members
public string loginID = null;


#region Singleton Instance stuff
private static MainController me = null;
private void MainController() { }
public static Instance {
    get {
        if(me == null) {
            me = new MainController();
        }
        return me;
    }
}
#endregion


//all public methods
public void Init(someargshere) {
    //TODO some init like load config files, etc.
}
public void Dispose() {
    //TODO cleanup
}
public void ClearSession() {
    loginID = "";
}

public void ShowLoginForm() {
    if(loginForm!=null) {
        loginForm.Dispose();
        loginForm == null;
    }

    loginForm = new LoginForm();
    loginForm.Show();
    loginForm.BringToFront();
}

//etc
}

Итак, самый первыйто, что вы делаете в коде Program.cs - это инициализация вашего основного контроллера

main(string[] args) {
    //start a controller
    MainController.Instance.Init(passomeargs if needed);

    //now fire off our main form
    Application.Run(new MainForm());
}

Теперь все формы после этого могут обращаться к своим данным через MainController

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

Удачи

...