1

リアクティブエクステンションについてもっと学びたいと思っていますが、実際の例を見つけるのは非常に難しいので、自分でトレーニングすることができます。

ToggleButton数日前、Mouse Enter、Leave Checked Uncheckedイベントを書いていることに気づきましたが、リアクティブエクステンションを使用して単純化できるかどうか疑問に思っています。

目標は次のとおりです。

を指定するToggleButtonと、カーソルを合わせてチェックされていない場合、ポップアップが表示され、マウスがボタンまたはポップアップの上にない場合はポップアップが閉じます。

トグルボタン(チェック済み)を押すと、ボタンがオフになるまでポップアップが開いたままになり(マウスのEnter Leaveイベントは無視されます)、その後、マウスのホバー動作が再び開始されます。

また、ポップアップが外部で閉じられている場合は、トグルボタンが自動的にオフになります。(これは、いくつかのバインディングとデータトリガーを使用して実装できることはわかっていますが、リアクティブ拡張ロジックを実行したいと思います)

今私は次のものを持っています:

    private void ToggleButton_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
    {
        if (!ToggleButton.IsChecked ?? false)
            Popup.IsOpen = true;
    }

    private void ToggleButton_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
    {
        if (!Popup.Child.IsMouseOver && !(TaskManagerTab.IsChecked ?? false))
        {
            Popup.IsOpen = false;
            return;
        }

        popup.Child.MouseLeave +=  Popup_MouseLeave;
    }

    void Popup_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
    {
        Popup.Child.MouseLeave -=  Popup_MouseLeave;

        if (!ToggleButton.IsMouseOver && !(ToggleButton.IsChecked ?? false))
        {
            Popup.IsOpen = false;
            return;
        }
    }

    private void ToggleButton_CheckedChanged(object sender, System.Windows.RoutedEventArgs e)
    {
        Popup.IsOpen = ToggleButton.IsChecked ?? false;

        if (Popup.IsOpen)
            Popup.Closed += Popup_Closed;
    }

    void Popup_Closed(object sender, System.EventArgs e)
    {
        Popup.Closed -= Popup_Closed;

        ToggleButton.IsChecked = false;
    }
}

大まかなバージョンにしますが、どうやって始めたらいいのか本当にわかりません。

ありがとうございました!

アップデート:

私はこれを思いついたのですが、パフォーマンスについてはよくわかりません。トグルボタンがオフになっていると、繰り返すことができないようです。

var mouseEnterSaveBtn = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(h => SaveBtn.MouseEnter += h,
                                                                       h => SaveBtn.MouseEnter -= h);

        var mouseLeaveList = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(h => popup.MouseLeave += h,
                                                                       h => popup.MouseLeave -= h);

        var toggleBtnChecked =
            Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(h => SaveBtn.Checked += h,
                                                                            h => SaveBtn.Checked -= h);

        var allCloseEvents = mouseLeaveList.Merge(mouseLeaveList);

        mouseEnterSaveBtn.TakeUntil(toggleBtnChecked).Subscribe(pattern =>
                                                                    {
                                                                        popup.Visibility = Visibility.Visible;

                                                                        allCloseEvents.TakeUntil(toggleBtnChecked).
                                                                            Subscribe(eventPattern =>
                                                                                          {
                                                                                              if (!popup.IsMouseOver && !popup.IsMouseOver)
                                                                                                  popup.Visibility = Visibility.Collapsed;
                                                                                          });

                                                                    });
4

1 に答える 1

5

それは私がすることにかなり近いです。ただし、私が提案する1つのことは、オブザーバブル内でオブザーバブルをサブスクライブする必要があると感じたときはいつでも(ネストされたサブスクライブ呼び出しに注意してください)、おそらくそれらのオブザーバブルを組み合わせてサブスクライブできるということです

var mouseIn = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>
    (
        h => SaveBtn.MouseEnter += h,
        h => SaveBtn.MouseEnter -= h
    );

var mouseOut = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>
    (
        h => popup.MouseLeave += h,
        h => popup.MouseLeave -= h
    );

var isMouseOver = mouseIn
    .Select((o,e) => true)
    .Merge(mouseOut
        .Select((o,e) => false));

var toggleBtnChecked = Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>
    (
        h => SaveBtn.Checked += h,
        h => SaveBtn.Checked -= h
    )
    .Select((o,e) => (o as ToggleButton).Checked);

var shouldShow = isMouseOver
    .DistinctUntilChanged()
    .CombineLatest(toggleBtnChecked, (mouse, pressed) => pressed || mouse);

shouldShow.Subscribe
(
    shouldBeVisible =>
    {
        popup.Visibility = shouldBeVisible ? Visibility.Visible : Visibility.Collapsed;
    }
);
于 2012-07-13T18:04:51.943 に答える