Как отличить в событии C #, если изменение было сделано из кода или пользователем? - PullRequest
26 голосов
/ 27 ноября 2011

У меня есть простой TextBox, который в начале пуст.У меня есть простое событие _TextChanged, чтобы узнать, когда пользователь изменил что-либо в этом TextBox.Однако событие запускается, если я сам что-то с ним делаю из кода.Как настройка textbox.Text = "Test"; или аналогичная.

    private void textNazwa_TextChanged(object sender, EventArgs e) {
        changesToClient = true;
    }

Как сделать так, чтобы событие срабатывало только на взаимодействие с пользователем, а не на изменение кода?

Ответы [ 4 ]

30 голосов
/ 01 марта 2013

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

private void textNazwa_TextCanged(object sender, EventArgs e)
{
    if ( !textNazwa.Focused) 
        return; 
}
19 голосов
/ 27 ноября 2011

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

private bool ignoreTextChanged;

private void textNazwa_TextCanged(object sender, EventArgs e)
{
    if (ignoreTextChanged) return;
}

Затем используйте это для установки текста вместо простого вызова Text = "...";:

private void SetTextboxText(string text)
{
    ignoreTextChanged = true;

    textNazwa.Text = text;

    ignoreTextChanged = false;
}

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

private void SetTextBoxText(TextBox box, string text)
{
    ignoreTextChanged = true;

    box.Text = text;

    ignoreTextChanged = false;
}

Тогда назовите это так:

SetTextBoxText(textNazwa, "foo");

Это выполнит то же самое, что и просто textNazwa.Text = "foo", но установит флаг, позволяющий вашему обработчику событий игнорировать событие.

6 голосов
/ 27 ноября 2011

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

например,

  textNazwa.TextChanged -= textNazwa_TextChanged;
  textbox.Text = "Test";
  textNazwa.TextChanged += textNazwa_TextChanged;

Если ваш метод имеет ту же область, в которой вы изменяете значение текстового поля, как textNazwa_TextChanged (например, оба находятся в форме), вы можетевместо этого установите флаг или, если вам этого недостаточно, вы можете использовать Chain Of Responsiblity, чтобы определить, должен ли метод textNazwa_TextChanged вызываться

2 голосов
/ 28 ноября 2011

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

public class Presenter : INotifyPropertyChanged
{
    public string MyTextValue { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;
    /// Create a method here that raises the event that you call from your setters..
}

И затем в вашем коде Windows Forms вам потребуется набор bindingSource для вашего Presenter и добавление привязки к вам textBoxes:

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

private BindingSource myPresenterSource ;
this.myPresenterSource = new System.Windows.Forms.BindingSource(this.components);
// Some time later in the

((System.ComponentModel.ISupportInitialize)(this.myPresenterSource )).BeginInit();
// you set the DataSource of your BindingSource
// m_SettingsBindingSource
//
this.myPresenterSource .DataSource = typeof(Presenter );

// and when you create your TextBox you do this :
this.YourTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text",
   this.myPresenterSource, "MyTextValue", true,
   System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));

Затем в InitializeComponent вы устанавливаете источник следующим образом:

myPresenterSource.DataSource = new Presenter();

Проверьте больше ресурсов, ища, как реализовать Movel-View-Presenter (MVP) в Windows Forms.

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