Как отличить событие С#, если изменение было сделано из кода или пользователя?
У меня есть простой TextBox
, который пуст в начале. У меня есть простое событие _TextChanged, чтобы узнать, когда пользователь изменил что-либо в этом TextBox
. Однако событие срабатывает, если я сам что-то делаю с ним изнутри кода. Как настройка textbox.Text = "Test";
или аналогичная.
private void textNazwa_TextChanged(object sender, EventArgs e) {
changesToClient = true;
}
Как сделать событие только срабатывающим при взаимодействии с пользователем, а не с изменениями кода?
Ответы
Ответ 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.