2014-11-30 4 views
0

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

static void Main() 
{ 
    // Initialize DirectInput 
    var directInput = new DirectInput(); 

    // Find a Joystick Guid 
    var joystickGuid = Guid.Empty; 

    foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad, 
       DeviceEnumerationFlags.AllDevices)) 
     joystickGuid = deviceInstance.InstanceGuid; 

    // If Gamepad not found, look for a Joystick 
    if (joystickGuid == Guid.Empty) 
     foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick, 
       DeviceEnumerationFlags.AllDevices)) 
      joystickGuid = deviceInstance.InstanceGuid; 

    // If Joystick not found, throws an error 
    if (joystickGuid == Guid.Empty) 
    { 
     Console.WriteLine("No joystick/Gamepad found."); 
     Console.ReadKey(); 
     Environment.Exit(1); 
    } 

    // Instantiate the joystick 
    var joystick = new Joystick(directInput, joystickGuid); 

    Console.WriteLine("Found Joystick/Gamepad with GUID: {0}", joystickGuid); 

    //Query all suported ForceFeedback effects 
    var allEffects = joystick.GetEffects(); 
    foreach (var effectInfo in allEffects) 
     Console.WriteLine("Effect available {0}", effectInfo.Name); 

    //Set BufferSize in order to use buffered data. 
    joystick.Properties.BufferSize = 128; 

    // Acquire the joystick 
    joystick.Acquire(); 

    // Poll events from joystick 
    while (true) 
    { 
     joystick.Poll(); 
     var datas = joystick.GetBufferedData(); 
     foreach (var state in datas) 
      Console.WriteLine(state); 
    } 
} 

Я установил sharpdx и я могу видеть выход оси джойстика в консоли.

Теперь я хочу отображать данные о каждой оси в отдельном текстовом поле на моем пользовательском интерфейсе. Поэтому я изменил несколько строк кода:

joystick.Poll(); 
var data = joystick.GetBufferedData(); 
foreach (var state in data) 
{ 
    if (state.Offset == JoystickOffset.X) 
    { 
     textBox1.Text = state.Value.ToString(); 
    } 
} 

Так что это должно передавать данные в текстовое поле. Если я напишу здесь Console.Writeline(state.Value), я получу данные, которые я хочу отобразить. Проблема в том, что этот while loop блокирует пользовательский интерфейс.

Я хотел бы поставить этот цикл while в private void timer_tick и установить частоту обновления 10 миллисекунд. Но я не знаю, как обращаться к переменным типа var joystick в отдельной функции. Я также прочитал, что это можно сделать с асинхронным программированием. К сожалению, я застрял сейчас.

Может ли кто-нибудь помочь мне с таким простым решением, как это возможно? Пример кода был бы замечательным.

+0

У меня может быть ответ, но я не разработчик C#. Переменные данные представляют собой массив элементов, а в цикле foreach переменная 'state' является элементом этой итерации. Это правильно? – JuanBonnett

+0

это WinForm или WPF? – kennyzx

ответ

1

Предположим, вы код с WinForm (выведено из blocking my UI form в ваш вопрос).

Добавьте таймер к вашей форме от дизайнера.

И добавьте эти строки в .ctor формы в:

public partial class JoyStickForm : Form 
{ 
    public JoyStickForm() 
    { 
     InitializeComponent(); 

     // ...Other initialization code has been stripped... 

     // Instantiate the joystick 
     var joystick = new Joystick(directInput, joystickGuid); 

     //Console.WriteLine("Found Joystick/Gamepad with GUID: {0}", joystickGuid); 

     timer1.Interval = 100; 
     timer1.Tick += (s, e) => 
      { 
       joystick.Poll(); 
       var lastState = joystick.GetBufferedData().Last(); //only show the last state 

       if (lastState != null) 
       { 
        if (lastState.Offset == JoystickOffset.X) 
        { 
         textBox1.Text = lastState.Value.ToString(); 
        } 
       } 
      }; 

     //start the timer 
     timer1.Enabled = true; 
    } 
} 

Пояснение:

  1. Освежающая скорость 100 раз в секунду излишне быстро, помните освежающую скорость большинство мониторов около 60 Гц. Я установил его как 100 мс (10 повторений в секунду), что приемлемо.

  2. Используя lambda expression, у вас есть доступ к переменным типа var joystick из обработчика галочки таймера.

  3. В каждом освещении на TextBox отображается только последнее состояние данных.