Reputation: 9081
I had this code
View
<DataGrid x:Name="dgFactures" ScrollViewer.VerticalScrollBarVisibility="Auto" Width="auto">
<i:Interaction.Triggers>
<i:EventTrigger EventName="ScrollChanged">
<cmd:EventToCommand Command="{Binding ScrollChangedCommand}" PassEventArgsToCommand="True"></cmd:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Hébergement">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Hebergement, Converter={StaticResource NullToFalse}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<cmd:EventToCommand Command="{Binding HebergementCommand}" PassEventArgsToCommand="True"></cmd:EventToCommand>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<cmd:EventToCommand Command="{Binding HebergementCommand}" PassEventArgsToCommand="True"></cmd:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
ViewModel
public RelayCommand<RoutedEventArgs> HebergementCommand { get; set; }
public RelayCommand<ScrollChangedEventArgs> ScrollChangedCommand { get; set; }
HebergementCommand = new RelayCommand<RoutedEventArgs>((e) =>
{
PropertyInfo IsChekedInfo = e.Source.GetType().GetProperty("IsChecked");
bool isChecked = (bool)IsChekedInfo.GetValue(e.Source, null);
Hebergement = isChecked;
});
ScrollChangedCommand = new RelayCommand<ScrollChangedEventArgs>((e) =>
{
if (e.HorizontalChange != 0)
{
// Do stuff..
}
});
The problem is :
Checked
event is fired and the ScrollChanged
event did not.ScrollChanged
didn't fired at allI need to know:
Thanks
Upvotes: 1
Views: 1678
Reputation: 5666
Your issue is caused by the way that EventTriggerBase
works. If you take a look to its code you can see this:
private void RegisterEvent(object obj, string eventName)
{
Type type = obj.GetType();
EventInfo @event = type.GetEvent(eventName);
if (@event == null)
{
if (this.SourceObject != null)
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionStringTable.EventTriggerCannotFindEventNameExceptionMessage, new object[]
{
eventName,
obj.GetType().Name
}));
}
return;
}
/* and so on... */
}
However the point is that it uses reflection to find the event which will be triggered. So it cannot find attached events attached to a FrameworkElement (in your case the DataGrid).
For fixing this issue, write your own EventTrigger:
public class AttachedEventTrigger : EventTriggerBase<DependencyObject>
{
public RoutedEvent RoutedEvent { get; set; }
private FrameworkElement AssociatedElement
{
get
{
IAttachedObject attachedObject = AssociatedObject as IAttachedObject;
FrameworkElement associatedElement = AssociatedObject as FrameworkElement;
if (attachedObject != null)
{
associatedElement = attachedObject.AssociatedObject as FrameworkElement;
}
return associatedElement;
}
}
protected override void OnAttached()
{
FrameworkElement associatedElement = AssociatedElement;
if (associatedElement == null)
{
throw new InvalidOperationException();
}
if (RoutedEvent != null)
{
associatedElement.AddHandler(RoutedEvent, new RoutedEventHandler(OnRoutedEvent));
}
}
protected override void OnDetaching()
{
FrameworkElement associatedElement = AssociatedElement;
if (RoutedEvent != null)
{
associatedElement.RemoveHandler(RoutedEvent, new RoutedEventHandler(OnRoutedEvent));
}
}
private void OnRoutedEvent(object sender, RoutedEventArgs args)
{
OnEvent(args);
}
protected override string GetEventName()
{
if (RoutedEvent != null)
{
return RoutedEvent.Name;
}
return String.Empty;
}
}
You can use it in this way:
<DataGrid x:Name="dgFactures" ScrollViewer.VerticalScrollBarVisibility="Auto" Width="auto">
<i:Interaction.Triggers>
<local:AttachedEventTrigger RoutedEvent="ScrollViewer.ScrollChanged">
<!-- your actions -->
</local:AttachedEventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
<!-- your columns -->
</DataGrid.Columns>
</DataGrid>
I hope this sample can help you.
Upvotes: 2