Остановка нескольких событий из цикла - PullRequest
1 голос
/ 05 августа 2011

У меня есть функция, предназначенная для того, чтобы мой пользователь мог переместить набор объектов (аэропорт) в новое место.

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

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

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

Спасибо

Ответы [ 2 ]

1 голос
/ 05 августа 2011

Предполагается, что вы используете Windows Forms:

// this.ckPosition.CheckedChanged += new System.EventHandler(this.ckPosition_CheckedChanged);
private void ckPosition_CheckedChanged(object sender, EventArgs e)
{
  txtX.Enabled = txtY.Enabled = ckPosition.Checked;
  numBearing.Enabled = numDistance.Enabled = !ckPosition.Checked;
}

// this.txtX.TextChanged += new System.EventHandler(this.Position_TextChanged);
// this.txtY.TextChanged += new System.EventHandler(this.Position_TextChanged);
private void Position_TextChanged(object sender, EventArgs e)
{
  if (ckPosition.Checked)
  {
    // Replace with your calculations
    numBearing.Value = Convert.ToInt32(txtX.Text);
    numDistance.Value = Convert.ToInt32(txtY.Text);
  }
}

// this.numBearing.ValueChanged += new System.EventHandler(this.BearingDistance_ValueChanged);
// this.numDistance.ValueChanged += new System.EventHandler(this.BearingDistance_ValueChanged);
private void BearingDistance_ValueChanged(object sender, EventArgs e)
{
  if (ckPosition.Checked == false)
  {
    // Replace with your calculations
    txtX.Text = numBearing.Value.ToString();
    txtY.Text = numDistance.Value.ToString();
  }
}

Пока вы не измените положение в обработчике событий положения или направление / расстояние в его обработчике, не должно быть никакого "зацикливания" событий.

0 голосов
/ 05 августа 2011

Я знаю, что это, вероятно, большая производительность, нет-нет, но вы пытались найти происхождение вашего события, используя отражение, чтобы определить, является ли это перенаправленным событием или нет? Вы можете посмотреть вверх по стеку, чтобы выяснить, является ли событие перенаправленным, или вы можете прервать его, если глубина стека вызовов становится нелепой. Или, если вы вызываете события TextChanged вручную, вы можете извлечь из класса eventArgs передать свои собственные события eventArgs, а затем прервать, если eventArgs является вашим пользовательским типом, или использовать пользовательские событияArgs для передачи информации о состоянии, чтобы помочь вам. Или, может быть, вы можете поменять событие TextChanged, находящееся в элементе управления, на аналогичный собственный обработчик события.

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