Клавиатура «Shift» для мобильных устройств аналогична функциональности с помощью RX.Net - PullRequest
0 голосов
/ 09 октября 2018

Работа над проектом, в котором мне нужно эмулировать функциональность кнопки «Shift» на мобильных клавиатурах;т. е. при нажатии он переключает состояние переключения во включенное состояние, а затем после нажатия другой клавиши возвращается в выключенное положение, но при удержании он остается включенным, пока нажаты другие клавиши, и возвращается только после повторного нажатия / удержания.Я недавно изучал RX и хотел попробовать это как часть этого.

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

ShiftDown = Observable.FromEventPattern(ShiftBtn, "PreviewMouseLeftButtonDown");
ShiftUp = Observable.FromEventPattern(ShiftBtn, "PreviewMouseLeftButtonUp");

ShiftClickedEvent = ShiftDown.Select(_ => ShiftUp.TakeUntil(Observable.Timer(TimeSpan.FromMilliseconds(250))))
            .Switch()
            .StartWith(new object());

ShiftHeldEvent = ShiftDown.Select(_ => Observable.Timer(TimeSpan.FromMilliseconds(1000)).TakeUntil(ShiftUp))
            .Switch()
            .StartWith(0);

IObservable<bool> ShiftState= Observable.CombineLatest(ShiftClickedEvent, ShiftHeldEvent,  (x, y) => new object())
            .Scan(false, (currentState, z) => !currentState)
            .StartWith(false)
            .DistinctUntilChanged();

Просто пытаюсь выяснить, насколько далеко я от базы.Цени любую помощь.

РЕДАКТИРОВАТЬ

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

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
    ShiftState = Observable.FromEventPattern(ShiftButton, "Click")
        .Select(_ => "shift");
    ShiftHoldState = Observable.FromEventPattern(ShiftButton, "MouseRightButtonDown")
        .Select(_ => "lock");
    CtrlState = Observable.FromEventPattern(CtrlButton, "Click")
        .Select(_ => "ctrl");
    PosState = Observable.FromEventPattern(POSButton, "Click")
        .Select(_ => "pos");

    KeyPress = Observable.Merge(
        FindLogicalChildren<HMKEnglishKey>(this).Select(
            o => Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
                h => o.Click += h,
                h => o.Click -= h
                )
                .Select(_ => "default")
            ));

    ModState = Observable.Merge(ShiftState, PosState, CtrlState, ShiftHoldState, KeyPress)
            .Scan("default" , (prev, current) => UpdateMods(prev, current))
            .StartWith("default")
            .DistinctUntilChanged();

    TestButton.Init();
}

private string UpdateMods(string prev, string current)
{
    string returnVal =
        (prev == "lock" && current == "default") ? "lock"
        : (prev == "lock" && current == "shift") ? "default"
        : prev == current ? "default" : current;
    return returnVal;
}

* Примечание. Оказывается, удержание сенсорного экрана в Windows 10 считается щелчком правой кнопки мыши, поэтому я смог использовать его дляподражать долгое удержание.Я все еще могу возиться со старыми мыслями, чтобы сделать его совместимым с мышью, но пока он работает.

1 Ответ

0 голосов
/ 11 октября 2018

Закончилось переходом к другому подходу, см. Исправленный код в посте

...