Странное поведение if-else

192
28 октября 2018, 16:50

Метод обрабатывает нажатие клавишы на клавиатуре (глобальный хук) и скрывает элементы на экране. Однако почему-то после активации if(!SomeOpened) сразу же активируется и блок else.

private static bool SomeOpened = false;
static private void _hook_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
    if (e.KeyCode == Keys.M || e.KeyCode == Keys.E)
    {
        if (!SomeOpened)
        {
            form.Dispatcher.Invoke(new Action(() => {
                form.Ellipse0.Visibility = Visibility.Hidden;
                form.Point0.Visibility = Visibility.Hidden;
            }));
        }
        else
        {
            form.Dispatcher.Invoke(new Action(() => {
                form.Ellipse0.Visibility = Visibility.Visible;
                form.Point0.Visibility = Visibility.Visible;
            }));
        }
        SomeOpened = !SomeOpened;
    }
}

Либо у меня глюки, либо такого быть не должно...

Answer 1

Дисклеймер

Данный вопрос является очень "ситуационным", как выяснилось в обсуждении, у автора где-то неявно происходит создание второго инстанса класса с точно таким же обработчиком такого события (это было выяснено путем сравнения this этих объектов). Поскольку поиск по коду ничего не дал - было принято сделать "костыльное решение" с e.Handled = true. Для всех последующих пользователей: если вы столкнулись с похожей проблемой - вы, скорее всего, подписали два одинаковых обработчика из-за копии класса, например.

private static bool SomeOpened = false;
private void _hook_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
    if (LastWindowIsTABG)
    {
        if (e.KeyCode == Keys.M || e.KeyCode == Keys.E)
        {
            e.Handled = true;
            if (!SomeOpened)
            {
                form.Dispatcher.Invoke(new Action(() => {
                    form.Ellipse0.Visibility = Visibility.Hidden;
                    form.Point0.Visibility = Visibility.Hidden;
                }));
            }
            else
            {
                form.Dispatcher.Invoke(new Action(() => {
                    form.Ellipse0.Visibility = Visibility.Visible;
                    form.Point0.Visibility = Visibility.Visible;
                }));
            }
            SomeOpened = !SomeOpened;
        }
    }   
}
Answer 2

логика, ты где

SomeOpened -  что-то открыто
if (!SomeOpened) Visibility.Hidden - если не открыто прячем
if (!) else - тоже странная конструкция

а это

    if (SomeOpened)
        SomeOpened = false;
    else
        SomeOpened = true;

нельзя записать так?

SomeOpened = !SomeOpened
private static bool SomeOpened = false;
static private void _hook_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
    if (LastWindowIsTABG && (e.KeyCode == Keys.M || e.KeyCode == Keys.E))
    {
        if (SomeOpened)
        {
            form.Dispatcher.Invoke(new Action(() => {
                form.Ellipse0.Visibility = Visibility.Hidden;
                form.Point0.Visibility = Visibility.Hidden;
            }));
        }
        else
        {
            form.Dispatcher.Invoke(new Action(() => {
                form.Ellipse0.Visibility = Visibility.Visible;
                form.Point0.Visibility = Visibility.Visible;
            }));
        }
        SomeOpened = !SomeOpened;
    }    
}

далее предположение глядя на доки

https://msdn.microsoft.com/ru-ru/library/system.windows.forms.keyeventargs(v=vs.110).aspx

и

https://stackoverflow.com/a/2907638/4794368

переменная и функция должны быть экземпляром объекта а не конструктора, то есть static - лишний.

так же можно завесть счётчик. который будет увеличиваться при каждом вызове _hook_KeyUp и сравнивать соответствует ли он "нажатию".

в общем должно получиться как-то так

public partial class MainWindow : Window
{
    LowLevelKeyboardHook hook;
    public MainWindow()
    {
        InitializeComponent();
        hook = new LowLevelKeyboardHook();
        hook.KeyUp += _hook_KeyUp;
    }
    private bool SomeOpened = true;
    private void _hook_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        if (LastWindowIsTABG && (e.KeyCode == Keys.M || e.KeyCode == Keys.E))
        {
            if (SomeOpened)
            {
                form.Dispatcher.Invoke(new Action(() => {
                    form.Ellipse0.Visibility = Visibility.Hidden;
                    form.Point0.Visibility = Visibility.Hidden;
                }));
            }
            else
            {
                form.Dispatcher.Invoke(new Action(() => {
                    form.Ellipse0.Visibility = Visibility.Visible;
                    form.Point0.Visibility = Visibility.Visible;
                }));
            }
            SomeOpened = !SomeOpened;
        }    
    }

}
READ ALSO
Cбой операции во время установки NLog.Configuration

Cбой операции во время установки NLog.Configuration

Cбой во время установки НЛог там говориться что оно уже установлено но как можно включить это в референсес в Visual Studio 2012 Идет попытка разрешить...

208
Математика с большими числами и Biginteger врет

Математика с большими числами и Biginteger врет

Нужно производить простые арифметические действия над большими числами на C#Использовал библиотеку System

169
System.NullReferenceException: “Ссылка на объект не указывает на экземпляр объекта.”

System.NullReferenceException: “Ссылка на объект не указывает на экземпляр объекта.”

Пытаюсь победить ошибку уже 4 день, уже весь интернет облазил, пересмотрел много решений, но так и не приблизился к решению проблемы :(

265
Мульти тач как в Piano Tile

Мульти тач как в Piano Tile

Каким методом реализовать данную функцию? Если touchcounts, то отслеживает только количество нажатий

164