简体   繁体   中英

WPF Datagrid's OnGeneratingColumn Not firing when using Event Triggers

I am trying to test this at a simple level where I have the following TasksDatagridView.xaml:

<UserControl x:Class="Example.Views.TasksDatagridView" ...>
    <UserControl.Resources>
        <local:CompleteConverter x:Key="completeConverter" />
        <local:Tasks x:Key="tasks" />
        <CollectionViewSource x:Key="cvsTasks" Source="{Binding Path=tasks}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="ProjectName"/>
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </UserControl.Resources>
    <Grid>
        <DataGrid x:Name="myDG" AutoGenerateColumns="True" ItemsSource="{Binding Source={StaticResource cvsTasks}}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="AutoGeneratingColumn">
                    <i:InvokeCommandAction Command="{Binding GenColumns}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </DataGrid>
    </Grid>
</UserControl>

In my TasksDatagridView.xaml.cs I tried both setting the datacontext first this.DataContext = new ViewModels.TaskDgVm() and then InitializeComponent() and vice versa.

In my main window MainWindow.xaml I reference the control like such:

<Window x:Name="MainWindow" x:Class="Example.Views.MyMainWindowView" ...>
  <Grid>
    <local:TasksDatagridView x:Name="tview" />
  </Grid>
</Window>

This is a derived example that shows the point so please excuse mispelling. So I am having two issues:

  1. In the MainWindow.xaml line where i reference the control: <local:TasksDatagridView x:Name="tview" /> it says it threw a system.exception, yet the code still compiles and runs fine.

  2. AutoGeneratingColumn is not being fired.

Really I am trying to figure out #2 and why this specific event is not firing. Right now I have a simple print in the execute method and when replacing the event name with a simple click or loaded event for the datagrid the command works fine and just about any other event gets fired, which tells me its not something in my viewmodel or delegate command class. Any thoughts on why the autogenerate column event is not working with command? Note I have made sure the event name is not misspelled.

Edit: After posting question I found a related question here: MVVM - WPF DataGrid - AutoGeneratingColumn Event However they use mvvm-light toolkit where I am using the expression blend interactivity library. Although the same answer may apply to both questions, they are indeed two separate toolkits.

So based on this thread MVVM - WPF DataGrid - AutoGeneratingColumn Event I believe the visual tree is not getting constructed during some of these events.

But there is an alternative provided that solves the problem while avoiding code behind:

public class AutoGeneratingColumnEventToCommandBehaviour
{
    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.RegisterAttached(
            "Command", 
            typeof(ICommand), 
            typeof(AutoGeneratingColumnEventToCommandBehaviour),
            new PropertyMetadata(
                null,
                CommandPropertyChanged));

    public static void SetCommand(DependencyObject o, ICommand value)
    {
        o.SetValue(CommandProperty, value);
    }

    public static ICommand GetCommand(DependencyObject o)
    {
        return o.GetValue(CommandProperty) as ICommand;
    }

    private static void CommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var dataGrid = d as DataGrid;
        if (dataGrid != null)
        {
            if (e.OldValue != null)
            {
                dataGrid.AutoGeneratingColumn -= OnAutoGeneratingColumn;
            }
            if (e.NewValue != null)
            {
                dataGrid.AutoGeneratingColumn += OnAutoGeneratingColumn;
            }
        }
    }

    private static void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        var dependencyObject = sender as DependencyObject;
        if (dependencyObject != null)
        {
            var command = dependencyObject.GetValue(CommandProperty) as ICommand;
            if (command != null && command.CanExecute(e))
            {
                command.Execute(e);
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM