XAML: состояние сброса переключателя

Я хочу выполнить следующее. У меня есть ToggleSwitch, обработчик событий которого Toggled выполняет какое-то действие. Если это действие не удается, я хочу сбросить состояние ToggleSwitch до того, что было.

Я достигаю этого, делая: toggleSwitch.IsOn = !toggleSwitch.IsOn;

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

Вот мой полный пример кода

    private async void ToggleSwitch_Toggled(object sender, Windows.UI.Xaml.RoutedEventArgs e)
    {
        ToggleSwitch toggleSwitch = sender as ToggleSwitch;
        success = dummyService.performAction(toggleSwitch.IsOn); 
        if (!success )
        {
            //raise dialog to inform user here
            toggleSwitch.IsOn = !toggleSwitch.IsOn;
        }
    }

Я знаю, что такое поведение уже реализовано в разных приложениях, поэтому добиться этого несложно.


person Rasetech    schedule 28.11.2015    source источник


Ответы (2)


Вы можете сделать что-то вроде этого, отсоединив и повторно прикрепив ваше событие:

if (!success )
{
    toggleSwitch.Toggled -= ToggleSwitch_Toggled;
    try
    {
      toggleSwitch.IsOn = !toggleSwitch.IsOn;
    }
    finally
    {
      toggleSwitch.Toggled += ToggleSwitch_Toggled;
    }
}
person Giangregorio    schedule 28.11.2015
comment
Спасибо за ваш совет, звучит многообещающе, но что такое yourToggledEvent. - person Rasetech; 28.11.2015
comment
ToggleSwitch_Toggled это yourToggledEvent. Он заставляет вас отписаться от события, затем изменить значение переключателя и, наконец, повторно подписаться. Это предотвратит повторный выстрел. - person Felix Castor; 28.11.2015
comment
Я не понимаю вас здесь - как мне получить событие внутри метода ToggleSwitch_Toggled? есть только отправитель объекта params и RoutedEventArgs - person Rasetech; 28.11.2015
comment
ToggleSwitch_Toggled есть. Я обновлю свой ответ, чтобы вы могли лучше понять его. - person Giangregorio; 28.11.2015
comment
Событие toggleSwitch.Toggled запускается toggleSwitch. Вы можете указать, что делает это событие, используя операторы -= или +=, как показано в его коде. - person Felix Castor; 28.11.2015
comment
Определенно лучший способ сделать это. Я пришел сюда, чтобы дать точно такой же ответ. Отмените подписку на событие из метода, измените свойство, а затем повторно подпишитесь :) - person James Croft; 28.11.2015

Я предполагаю, что вы хотите выполнить операцию только при включенном toggleswitch. Если это так, то вы можете попробовать это:

private async void ToggleSwitch_Toggled(object sender, Windows.UI.Xaml.RoutedEventArgs e)
    {
        ToggleSwitch toggleSwitch = sender as ToggleSwitch;

        if(toggleSwitch == null || !toggleSwitch.IsOn)
          return;
        // You are missing your await statement....
        success = await dummyService.performAction(toggleSwitch.IsOn); 
        if (!success )
        {
            //raise dialog to inform user here
            toggleSwitch.IsOn = !toggleSwitch;
        }
    }
person Felix Castor    schedule 28.11.2015
comment
Спасибо за ваш совет, но мои действия должны быть выполнены в любом случае - person Rasetech; 28.11.2015
comment
Тогда ответ Джангрегорио — правильный путь. - person Felix Castor; 28.11.2015
comment
Событие должно возвращать void, а не Task (это редкий случай). Вы пытались создать код? - person Romasz; 28.11.2015
comment
@Romasz Вам следует обратиться к Async/Await — лучшие практики. Я думал то же самое, что и вы, но возвращаемые типы не такие, какими кажутся. - person Felix Castor; 28.11.2015
comment
@Romasz После перечитания моей собственной ссылки кажется, что в этом случае вы правы. Обработчики событий должны иметь возвращаемый тип void.... Поправлю. - person Felix Castor; 28.11.2015