Цикл C # при нажатой кнопке mousedown - PullRequest
2 голосов
/ 10 октября 2011

Я хотел бы использовать цикл при нажатой левой кнопке мыши:

  private void Loop_MouseDown(object sender, MouseEventArgs e)
        {
            while (e.Button==MouseButtons.Left)
            {
            //Loop
            }
        }

Я не могу использовать решение из этой темы:
C # как выполнить цикл, пока нажата кнопка мышиdown , потому что я посылаю данные через RS232 и использую таймер с собственным интервалом, не работает.Также любое решение из этой темы не работает для меня.Он также не может работать, как здесь:

 if (e.Button == MouseButtons.Left)
    {
        //loop
    }

Это решение также не работает:

bool isLooping = false;

//on mouse down
private void myControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
    isLooping = true;
    runLoop();
}

//on mouse up event
private void myControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
    isLooping = false;
}

//This is the main loop you care about.  Put this in your application
//This should go in its own thread
void runLoop() {
    while (isLooping) {
        //do stuff
    }
}

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

Так, как заставить это работать правильно?

Ответы [ 4 ]

2 голосов
/ 10 октября 2011

Используйте BackGroundWorker.Идеально подходит для вашей проблемы.

Поместите функцию цикла в работника и запускайте / останавливайте работника при событиях мыши.

0 голосов
/ 10 октября 2011

Эти сценарии очень сложны для реализации - посмотрите ваши обработчики и логические переменные для хранения состояния.

Я бы предложил использовать Реактивные расширения .

Edit:

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

var mouseDown = Observable.FromEvent<MouseButtonEventArgs>(source, "MouseDown"); 
var mouseUp = Observable.FromEvent<MouseButtonEventArgs>(image, "MouseUp"); 
var mouseMove = from evt in Observable.FromEvent<MouseEventArgs>(image, "MouseMove") 
  select evt.EventArgs.GetPosition(this);

использовать LINQ-to-Rx для запроса и фильтрации событий

var leftMouseDown = from evt in mouseDown 
  where evt.LeftButton == MouseButtonState.Pressed
  select evt; 

и составьте его, используя операторы Rx - пока не произойдет событие повышения мыши, занимайте все позиции, пока левая мышь не работает

var q = from position in leftMouseDown  
    from pos in mouseMove.Until(mouseUp) 
    select new { X = pos.X - imageOffset.X, Y = pos.Y - imageOffset.Y }; 

Наконец, подпишитесь на наблюдаемую последовательность позиций и делайте свое дело

q.Subsribe(value => { ... });

Слегка модифицированный код здесь .

0 голосов
/ 10 октября 2011

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

Эта страница может быть полезна:

http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

0 голосов
/ 10 октября 2011

Если использование таймера не сработает, вам необходимо отправить данные в другой поток и сообщить об этом из обработчика MouseUp.

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