Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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", но установит флаг, позволяющий вашему обработчику событий игнорировать событие.

Ответ 2

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

private void textNazwa_TextCanged(object sender, EventArgs e)
{
    if ( !textNazwa.Focused) 
        return; 
}

Ответ 3

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

например.

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

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

Ответ 4

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

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 вам понадобится привязка источника к вашему презентатору и добавьте привязку к вашим текстовым полям:

ИЗМЕНИТЬ

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.