Hi,

I am developing a WPF application in which I need to call MouseLeftButtonDown event in a single DataGridTextColumn.
For that I wrote some xaml code as :-

<DataGridTextColumn x:Name="myAge" Header="Age" Binding="{Binding Age, Mode=TwoWay}" IsReadOnly="True" Width="*">
    <DataGridTextColumn.CellStyle>
         <Style TargetType="DataGridCell">                            
            <EventSetter Event="MouseLeftButtonDown" Handler="{Binding MyAgeCommand}" />
         </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

But I am getting an "Object reference null" exception. I tried searching this over the Internet however all I found a solution in which I need to refer to an external AttachedCommandBehavior.dll but I don't want to do this.

All I need to ask is some way so that I can bind my Handler to MyAgeCommand as persently, I am unable to do that.

My ViewModel is :-

public DelegateCommand MyAgeCommand
{
    get
    {
       if (_myAgeCommand == null)
           _myAgeCommand = new DelegateCommand(MySelectedCell);
       return _myAgeCommand;
    }
}



private void MySelectedCell(object obj)
{
   // Rest of the code
}

Edited 2 Years Ago by KM499

No it is a bug. This Hotfix should work

Unfortunately, it means that you need to include this hotfix with your application redist.

Edit: Reading the bug report there is a workaround - Add the style as a dynamic resource reference or add it as a static resource to the xaml resource dictionary.

Edited 2 Years Ago by Ketsuekiame

Comments
Whish I had this WPF knowledge

Hi Ketsuekiame, thanks a lot for the reply.
I see Microsoft mentioning that "A NullReferenceException exception occurs when you run a .NET Framework 4.0-based WPF application that has events in a nested template".
However, I don't think I am using a nested template here, but still I am facing the same issue. I am not using any DataTemplates here but still the same exception comes. Anyways I'll try fixing this bug by your help and will surely inform you also :)

Edited 2 Years Ago by KM499

Hi, I tried this approach but this one gave another exception stating..."'XAML Node Stream: Missing EndMember for 'MyWPFPracticeApp.Views.MyDataGridResearch.System.Windows.FrameworkElement.Resources' before EndObject.'"

Here's my style :-

<UserControl.Resources>
   <Style x:Key="MyAgeStyle" TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
      <EventSetter Event="MouseLeftButtonDown" Handler="{Binding MyAgeCommand}" />
   </Style>
</UserControl.Resources>

I am using this style in <DataGridTextColumn x:Name="myAge" Header="Age" Binding="{Binding Age, Mode=TwoWay}" IsReadOnly="True" Width="*" CellStyle="{StaticResource MyAgeStyle}"/> and as you see there is no DataTemplate in this column. Please help if possible.

Edited 2 Years Ago by KM499

Did you try cleaning the solution and doing a full rebuild? This might be an issue with cached build objects.

Sure, here it is...

<UserControl x:Class="MyWPFPracticeApp.Views.MyDataGridResearch"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
             xmlns:interact="clr-namespace:MyWPFPracticeApp.GenericClasses"
             mc:Ignorable="d" 
             d:DesignHeight="400" d:DesignWidth="600">
    <UserControl.Resources>
        <Style x:Key="MyAgeStyle" TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
            <EventSetter Event="MouseLeftButtonDown" Handler="{Binding MyAgeCommand}" />
        </Style>
    </UserControl.Resources>
    <Grid>
        <DataGrid x:Name="dgEmployee" AutoGenerateColumns="False" ItemsSource="{Binding MyGridData, UpdateSourceTrigger=PropertyChanged}">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Path=IsChecked,Mode=TwoWay}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox IsEnabled="{Binding Path=IsChecked,Mode=TwoWay}" Text="{Binding Name, Mode=TwoWay}"></TextBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn x:Name="myAge" Header="Age" Binding="{Binding Age, Mode=TwoWay}" IsReadOnly="True" Width="*" CellStyle="{StaticResource MyAgeStyle}"/>
                <DataGridTextColumn Header="Department" Binding="{Binding Department, Mode=TwoWay}" IsReadOnly="True" Width="*" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>

The XAML seems valid and my IDE is happy enough with it. It may be one of your supporting resource libraries that's invalid.

Where are you storing your style resources?

I am not storing my styles anywhere and these are static resources which I am using inside this xaml only.
Also, I am not using any external libraries other than interactivity and interactions and already tried removing the same.
I didn't get what exactly the problem is.
I guess there may be a problem with the DelegateCommand class but I am not sure. Could you please take a look at my DelegateCommand also :-

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Diagnostics;

namespace MyWPFPracticeApp.GenericClasses
{
    public class DelegateCommand : ICommand
    {
        protected Action<object> _Execute;
        protected Predicate<object> _CanExecute;
        protected EventHandler _CanExecuteChanged = (o, e) => { };

        public DelegateCommand(Action<object> pExecute)
            : this(pExecute, null)
        {
        }
        public DelegateCommand(Action<object> pExecute, Predicate<object> pCanExecute)
        {
            if (pExecute == null)
                throw new ArgumentNullException("pExecute", "[RelayCommand] The action for a command cannot be null.");

            _Execute = pExecute;
            _CanExecute = pCanExecute;
        }
        public bool CanExecute(object pParameter)
        {
            if (_CanExecute != null)
            {
                return _CanExecute(pParameter);
            }
            return true;
        }
        public void Execute(object pParameter)
        {
            _Execute(pParameter);
        }
        public event EventHandler CanExecuteChanged
        {
            add { _CanExecuteChanged += value; }
            remove { _CanExecuteChanged -= value; }
        }
        public void SignalCanExecuteChanged()
        {
            if (_CanExecuteChanged != null)
                _CanExecuteChanged(this, new EventArgs());
        }
    }
}

Edited 2 Years Ago by KM499

The error you have means that the XAML is missing a closing tag somewhere.

Unfortunately, I couldn't compile your application because it couldn't find any of your resources.

Your delegate command seems ok.

Unfortunately I also cannot find any error in the closing of the tags here. Don't know how exactly should I proceed with this one...!!!

Hey, I found a solution to this one (however not exactly using the EventSetter but an easy replacement though). Just used Interaction command and parameter to be passed in the main DataGrid. I know it is not a perfect solution to the EventSetter problem but I am sure its the other way round of solving this problem also :)

<UserControl x:Class="MyWPFPracticeApp.Views.MyDataGridResearch"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             mc:Ignorable="d" 
             d:DesignHeight="400" d:DesignWidth="600">
    <UserControl.Resources>
        <Style x:Key="MyAgeStyle" TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="Maroon" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </UserControl.Resources>
    <Grid>
        <DataGrid x:Name="dgEmployee" AutoGenerateColumns="False" ItemsSource="{Binding MyGridData, UpdateSourceTrigger=PropertyChanged}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseDoubleClick">
                    <i:InvokeCommandAction Command="{Binding MyAgeCommand}" CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Path=IsChecked,Mode=TwoWay}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox IsEnabled="{Binding Path=IsChecked,Mode=TwoWay}" Text="{Binding Name, Mode=TwoWay}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn x:Name="myAge" Header="Age" Binding="{Binding Age, Mode=TwoWay}" IsReadOnly="True" Width="*" CellStyle="{DynamicResource MyAgeStyle}" />
                <DataGridTextColumn Header="Department" Binding="{Binding Department, Mode=TwoWay}" IsReadOnly="True" Width="*" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>

It is simply not possible, because EventSetter is not inherited from DependencyObject, does not support DependencyProperties system and that's why can't apply bindings to own properties

This question has already been answered. Start a new discussion instead.