Home > C#, MVVM, WinRT > A Behavior to close Flyouts via MVVM in Windows 8.1 Store apps

A Behavior to close Flyouts via MVVM in Windows 8.1 Store apps

04/02/2014

Some times ago we shown how to create an Attached Property that allows to hide a Flyout from a ViewModel.

In addition to this approach, we can also use a Behavior to obtain the same result. Suppose, for example, that we want to close the popup after executing a command in the ViewModel. First of all, we need to define a new Action:

public class CloseFlyoutAction : DependencyObject, IAction
{
    public object Execute(object sender, object parameter)
    {
        var flyout = sender as Flyout;
        if (flyout == null)
            throw new ArgumentException("CloseFlyoutAction can be used only with Flyout");

        flyout.Hide();

        return null;
    }
} 

This Action simply closes the Flyout control on which it is attached. Let’s see how to use it:

<Page
    ...
    DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
    xmlns:local="using:App1"
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    ...>

    <Button Content="Show">
        <Button.Flyout>
            <Flyout>
                <StackPanel Width="406">
                    <TextBox Header="Insert the value and tap the Send button:" />
                    <Button Content="Send" HorizontalAlignment="Right"
                         FontSize="16" Margin="0,10,0,0"
                         Command="{Binding SendCommand}" />
                </StackPanel>
                <i:Interaction.Behaviors>
                    <core:DataTriggerBehavior Binding="{Binding IsFlyoutClosed}"
                                              ComparisonCondition="Equal" Value="True">
                        <local:CloseFlyoutAction />
                    </core:DataTriggerBehavior>
                </i:Interaction.Behaviors>
            </Flyout>
        </Button.Flyout>
    </Button>

At lines 19-20 we have declared a DataTriggerBehavior that checks whether the IsFlyoutClosed property of the ViewModel becomes true and, in this case, executes the specificed action (line 21).

Finally, let’s see how the IsFlyoutClosed property is used in the ViewModel:

public class MainViewModel : ViewModelBase
{
    private bool isFlyoutClosed;
    public bool IsFlyoutClosed
    {
        get
        {
            return isFlyoutClosed;
        }
        set
        {
            this.Set(ref isFlyoutClosed, value);
            if (value)
                IsFlyoutClosed = false;
        }
    }

    public RelayCommand SendCommand { get; set; }

    public MainViewModel()
    {
        SendCommand = new RelayCommand(() =>
            {
                // ...
                IsFlyoutClosed = true;
            });
    }
}

The IsFlyoutClosed property is used in a “particular” way. It is set twice: the first one is the explicit assignment to true (line 25) when the command execution finishes. This raises the PropertyChanged event (line 12, in the Set method of MVVM Light Toolkit), and so the corresponding DataTriggerBehavior is processed, causing the CloseFlyoutAction to be executed. Then, the variable is automatically reset to false (line 14), so that it can be used to close the popup again, as described earlier.

About these ads
Categories: C#, MVVM, WinRT
Follow

Get every new post delivered to your Inbox.

Join 27 other followers

%d bloggers like this: