Проверьте введенный текст в приложении WinForm - PullRequest
2 голосов
/ 09 февраля 2010

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

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

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

Ответы [ 3 ]

2 голосов
/ 09 февраля 2010

Если вы используете привязку данных, вы можете реализовать в своих классах INotifyPropertyChanged (вручную или путем создания прокси-сервера времени выполнения), подписаться на событие PropertyChanged и выполнить отслеживание там.

Если нет, вы можете рекурсивно перебирать элементы управления в форме / пользовательском контроле, подписываться на соответствующие события для каждого элемента управления (например, TextChanged для TextBox, SelectedItemChanged для ComboBox элемента управления и т. Д.) И переадресация вызовов на ваши процедуры отслеживания.

1 голос
/ 09 февраля 2010

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

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

Интерфейс выглядит следующим образом:

public interface IEventService
{
    void RaiseChanged(object sender, EventArgs e);
    event EventHandler Changed;
}

Базовая реализация довольно проста, но я все равно ее включу:

public class EventService : IEventService
{
    public void RaiseChanged(object sender, EventArgs e)
    {
        EventHandler handler = Changed;
        if (handler != null)
            handler(sender, e);
    }

    public event EventHandler Changed;
}

Определите его в выбранном вами контейнере IoC и настройте его так, чтобы он вел себя как синглтон, или просто внедрите его как синглтон, если IoC будет слишком много работы; Я предполагаю, что вы идете с первым вариантом. Тогда ваш основной код формы выглядит так:

public class MainForm : Form
{
    private bool currentTaskChanged;

    public MainForm()
    {
        InitializeComponent();
        InitializeChangeEvents();
    }

    public void LoadTask(ITask task)
    {
        if (currentTaskChanged)
        {
            // Confirm whether or not to save changes
        }

        // Code to change the current task view here ...
        currentTaskChanged = false;
    }

    private void InitializedChangedEvents()
    {
        IEventService service = IoC.Resolve<IEventService>();
        service.Changed += TaskChanged;
    }

    private void TaskChanged(object sender, EventArgs e)
    {
        currentTaskChanged = true;
    }
}

Тогда довольно просто зачислить новые подзадачи / элементы управления:

public class CustomerSetupControl : UserControl
{
    public CustomerSetupControl()
    {
        InitializeComponent();
        InitializeChangeTriggers();
    }

    private void InitializeChangeTriggers()
    {
        IEventService service = IoC.Resolve<IEventService>();
        txtAccountNumber.TextChanged += service.RaiseChanged;
        txtName.TextChanged += service.RaiseChanged;
        chkIsVip.CheckedChanged += service.RaiseChanged;
        // etc.
    }
}

Вы можете теоретически автоматизировать некоторые из них, перебирая все дерево управления подзадачей, но это довольно сложно. Например, если одним из элементов управления является CheckBox, перехват события TextChanged действительно не поможет вам. Таким образом, вам нужно сделать это один за другим, чтобы убедиться, что вы действительно обнаруживаете правильное измененное событие для правильного элемента управления, а в некоторых случаях вы можете даже игнорировать изменения определенного элемента управления (т. Е. Возможно, есть поле со списком, которое просто меняет фильтр где-то без изменения каких-либо данных).

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

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

1 голос
/ 09 февраля 2010

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

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

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