在wpf应用程序

时间:2015-10-30 08:52:47

标签: c# .net wpf xaml mvvm

我有这个代码

查看

    <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>

视图模型

 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..
                }
            });

问题是:

  • 当我使用鼠标或点击滚动条在网格中滚动时:Checked事件被触发而ScrollChanged事件没有。
  • ScrollChanged根本没有被解雇

我需要知道:

  1. 为什么会这样?
  2. 我该如何解决?
  3. 由于

1 个答案:

答案 0 :(得分:2)

您的问题是由EventTriggerBase的工作方式引起的。如果您查看其代码,您可以看到:

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... */
}

但重点是它使用反射来查找将被触发的事件。因此找不到附加到FrameworkElement的attached events(在您的情况下是DataGrid)。

要解决此问题,请编写自己的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;
    }
}

您可以这样使用它:

<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>

我希望这个样本可以帮到你。