Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using interaction trigger to call visibility changed method WPF

Tags:

c#

wpf

xaml

What I would like to figure out is two things, how to get a trigger occurring when a user control's visibility is changed and passing the value of visibility through as a parameter.

For whatever reason the trigger doesn't seem to be firing. I have only just added in the ControlVisible parameter to show what I would like to happen, when testing it was not there and just had a messagebox inside to catch when visibility changed, as in the commented out method.

I am using 4.0 with Visual Studio 2010

Main Window View which contains the user control

<Window x:Class="bt.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:vm="clr-namespace:bt"
        xmlns:ctrls="clr-namespace:bt.Controls"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
        mc:Ignorable="d">

    <Grid>
        <ctrls:Login Visibility="{Binding DataContext.Vis,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window},Converter={StaticResource BooleanToVisibilityConverter}}" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="IsVisibleChanged">
                    <ei:CallMethodAction MethodName="VisibleTrigger" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ctrls:Login>
    </Grid>
</Window>

UserControl View Model:

namespace bt.Controls
{
    class LoginViewModel
    {
        public LoginViewModel()
        {
        }

        public void VisibleTrigger(bool ControlVisible)
        {
            if (ControlVisible)
            {
                MessageBox.Show("Start timer");
            }
            else
            {
                MessageBox.Show("Stop timer");
            }
        }

        //public void VisibleTrigger()
        //{
        //    MessageBox.Show("Changed");
        //}
    }
}
like image 853
Hank Avatar asked Feb 17 '14 02:02

Hank


1 Answers

First, we need to set TargetObject property to viewmodel/DataContext, because method to be invoked is available in the viewmodel :

......
<i:Interaction.Triggers>
    <i:EventTrigger EventName="IsVisibleChanged">
        <ei:CallMethodAction MethodName="VisibleTrigger" TargetObject="{Binding}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>
......

Second, EventTrigger doesn't seems to work specifically with IsVisibleChanged event. So code snippet above works for other event, but not IsVisibleChanged. We can find a workaround in the answer to this SO question, by using PropertyChangedTrigger to listen to Visibility property changed, instead of listening to IsVisibleChanged event :

<i:Interaction.Triggers>
    <ei:PropertyChangedTrigger Binding="{Binding Visibility, ElementName=MyControlName}">
        <ei:CallMethodAction  MethodName="VisibleTrigger" TargetObject="{Binding}"/>
    </ei:PropertyChangedTrigger>
</i:Interaction.Triggers>

Third, CallMethodAction doesn't seems to provide a way to pass parameter to the method. To be able to invoke a method with parameter we better use InvokeCommandAction instead of CallMethodAction as suggested here and also suggested by @Rohit in your previous question.

like image 75
har07 Avatar answered Oct 16 '22 06:10

har07