InvokeCommandAction for IsVisibleChanged Command not work
CodingOctocat opened this issue · 3 comments
I use MVVM Toolkit
and XamlBehaviorsWpf
, They worked fine until I started using the IsVisibleChanged
event, and I found that the event handler UserControl_IsVisibleChanged
was called correctly (no doubt), but the FooCommand
was not called.
To add, this should not be a problem with my code, as other event commands can be called (e.g. Loaded)
View:
<UserControl IsVisibleChanged="UserControl_IsVisibleChanged">
<i:Interaction.Triggers>
<i:EventTrigger EventName="IsVisibleChanged">
<i:InvokeCommandAction Command="{Binding FooCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</<UserControl>
Vm:
[RelayCommand]
private void Foo()
{
// not called.
}
Code-Behind:
private void UserControl_IsVisibleChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
// normal called.
}
Sample:
As stated in the bug issue template:
"Please upload or provide a link to a reproduction case. If no reproduction sample is included, this issue may be closed or ignored until a sample has been provided".
@brianlagunas Sorry, I forgot about the issue template requirement, now I added the sample.
Thanks for the sample. The reason this is happening is because the IsVisibileChanged
event is not the correct event type for the built-in EventTrigger
.
The IsVisibleChnaged
event is actually a DependencyPropertyChangedEventHandler
delegate, and does not have an EventArgs
object, but rather a struct of type DependencyPropertyChangedEventArgs
.
If you want to support this type of event, you'll need to provide a custom implementation of the event trigger. Here is an example of a very simple and incomplete approach you may take.
public class DependencyPropertyChangedEventTrigger : Microsoft.Xaml.Behaviors.EventTrigger
{
protected override void OnSourceChanged(object oldSource, object newSource)
{
RegisterEvent(newSource, GetEventName());
}
private void RegisterEvent(object obj, string eventName)
{
Type targetType = obj.GetType();
EventInfo eventInfo = targetType.GetEvent(eventName);
var eventHandlerMethodInfo = typeof(DependencyPropertyChangedEventTrigger).GetMethod("OnEventImpl", BindingFlags.NonPublic | BindingFlags.Instance);
eventInfo.AddEventHandler(obj, Delegate.CreateDelegate(eventInfo.EventHandlerType, this, eventHandlerMethodInfo));
}
private void OnEventImpl(object sender, DependencyPropertyChangedEventArgs eventArgs)
{
//todo: handle your event args and pass them as a proper EventArgs based class
this.OnEvent(new EventArgs());
}
}
<local:DependencyPropertyChangedEventTrigger EventName="IsVisibleChanged">
<i:InvokeCommandAction Command="{Binding BorderIsVisibleChangedCommand}" />
</local:DependencyPropertyChangedEventTrigger>
This should get you pointed in the right direction.