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
}

Recommended Answers

All 14 Replies

Requesting all if anyone could please help me with this :)

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.

commented: Whish I had this WPF knowledge +15

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

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.

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

Yes, I did but again facing the same issue.

Can you post the entire XAML? I think you're missing a </resources> tag somewhere.

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

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

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.