Hi,
Our team noticed that when a field in a XamDataGrid record is bound to a property that returns null, that property's setter gets re-evaluated multiple times when the record is loaded and also re-evaluates when the mouse hovers over the record.
This is having some very negative and adverse behavior for us since the grid control seems to be making an assumption about what null means, but from the data standpoint its a legitimate value. Yet, the grid doesn't treat it like any other value.
The only workaround I've found is to specify AlternateBinding with AlternateBindingRetentionMode="Retain". However, we have dozens of grids with hundreds of fields already declared, and it will be a massive PITA to go and migrate the field declarations for each.
1. Why does the grid re-evaluate fields that are null? Is this by design?2. Can this behavior be set on a global level so that alternate binding isn't specified?Thanks,BedoHere is a sample app that demonstrates the behavior: Simply brake where DoubleNullable and ObjectNull's getters return. Then run and move the mouse over the grid.
---- XAML -----
<Window x:Class="WpfApplication1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:dataPresenter="http://infragistics.com/DataPresenter"Title="MainWindow" Height="350" Width="525"><dataPresenter:XamDataGrid DataSource="{Binding Items}"/></Window>
---- CODE ----
using System.Collections.ObjectModel;using System.Windows;
namespace WpfApplication1 {public partial class MainWindow : Window {public MainWindow() {InitializeComponent();DataContext = new TestViewModel();}}
public class TestViewModel {public ObservableCollection<Item> Items { get; private set; }public TestViewModel() {Items = new ObservableCollection<Item> { new Item() };}}
public class Item {public double Double1 { get { return 1; } }public double DoubleNaN { get { return double.NaN; } }public double? DoubleNullable {//This gets called multiple times when the mouse hovers over the recordget { return null; }}
public object Object { get { return new object(); } }public object ObjectNull {//This gets called multiple times when the mouse hovers over the recordget { return null; }}
}}
Hello Bedo,
Thank you for your post.
I have been looking into it and the code snippet that you have provided. I created a short sample application based on your code and I could not manage to reproduce the issue that you have. Also I created a short video to show you how it works on my side Would you please modify the attached sample application with the functionality you are using. This way I would be able to further investigate this for you and provide you with more detailed information on this matter.
Looking forward to hearing from you.
Hi Zhivko,
With your exact example, I am still seeing the null issue. My breakpoints get hit. I've made absolutely no changes to your example. Perhaps the issue may be tied to the exact version of the assemblies?
I'm using:
Runtime Version: v4.0.30319
InfragisticsWPF4.DataPresenter.v14.2 14.2.20142.2081InfragisticsWPF4.Editors.v14.2 14.2.20142.2081InfragisticsWPF4.v14.2 14.2.20142.2081
This is the stack trace I get for 14.2:
> ReturnNull.exe!ReturnNull.Item.ObjectNull.get() Line 53 C# [Native to Managed Transition] System.dll!System.SecurityUtils.MethodInfoInvoke(System.Reflection.MethodInfo method, object target, object[] args) Unknown System.dll!System.ComponentModel.ReflectPropertyDescriptor.GetValue(object component) Unknown InfragisticsWPF4.DataPresenter.v14.2.dll!Infragistics.Windows.DataPresenter.DataRecord.GetCellValueHelper(Infragistics.Windows.DataPresenter.Field field) Unknown InfragisticsWPF4.DataPresenter.v14.2.dll!Infragistics.Windows.DataPresenter.DataRecord.GetCellValue(Infragistics.Windows.DataPresenter.Field field, bool useConverter) Unknown InfragisticsWPF4.DataPresenter.v14.2.dll!Infragistics.Windows.DataPresenter.Cell.Value.get() Unknown InfragisticsWPF4.DataPresenter.v14.2.dll!Infragistics.Windows.Automation.Peers.DataPresenter.CellAutomationPeer.System.Windows.Automation.Provider.IValueProvider.Value.get() Unknown InfragisticsWPF4.DataPresenter.v14.2.dll!Infragistics.Windows.Automation.Peers.DataPresenter.CellAutomationPeer.GetNameCore() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.ContextLayoutManager.fireAutomationEvents() Unknown PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayout() Unknown PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayoutCallback(object arg) Unknown PresentationCore.dll!System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork() Unknown PresentationCore.dll!System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() Unknown PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandlerCore(object resizedCompositionTarget) Unknown PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandler(object resizedCompositionTarget) Unknown WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) Unknown WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() Unknown WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state) Unknown mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown [Native to Managed Transition] [Managed to Native Transition] WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() Unknown PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Unknown PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Unknown PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) Unknown PresentationFramework.dll!System.Windows.Application.Run() Unknown ReturnNull.exe!ReturnNull.App.Main() C# [Native to Managed Transition] mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) Unknown Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() Unknown mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) Unknown mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() Unknown
.
I also just tried this with an older version, 13.2, and same issue.
> ReturnNull.exe!ReturnNull.Item.ObjectNull.get() Line 53 C# [Native to Managed Transition] System.dll!System.SecurityUtils.MethodInfoInvoke(System.Reflection.MethodInfo method, object target, object[] args) Unknown System.dll!System.ComponentModel.ReflectPropertyDescriptor.GetValue(object component) Unknown InfragisticsWPF4.DataPresenter.v13.2.dll!Infragistics.Windows.DataPresenter.DataRecord.GetCellValueHelper(Infragistics.Windows.DataPresenter.Field field) Unknown InfragisticsWPF4.DataPresenter.v13.2.dll!Infragistics.Windows.DataPresenter.DataRecord.GetCellValue(Infragistics.Windows.DataPresenter.Field field, bool useConverter) Unknown InfragisticsWPF4.DataPresenter.v13.2.dll!Infragistics.Windows.DataPresenter.Cell.Value.get() Unknown InfragisticsWPF4.DataPresenter.v13.2.dll!Infragistics.Windows.Automation.Peers.DataPresenter.CellAutomationPeer.System.Windows.Automation.Provider.IValueProvider.Value.get() Unknown InfragisticsWPF4.DataPresenter.v13.2.dll!Infragistics.Windows.Automation.Peers.DataPresenter.CellAutomationPeer.GetNameCore() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() Unknown PresentationCore.dll!System.Windows.ContextLayoutManager.fireAutomationEvents() Unknown PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayout() Unknown PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayoutCallback(object arg) Unknown PresentationCore.dll!System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork() Unknown PresentationCore.dll!System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() Unknown PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandlerCore(object resizedCompositionTarget) Unknown PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandler(object resizedCompositionTarget) Unknown WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) Unknown WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() Unknown WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state) Unknown mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown [Native to Managed Transition] [Managed to Native Transition] WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Unknown WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() Unknown PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Unknown PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Unknown PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) Unknown PresentationFramework.dll!System.Windows.Application.Run() Unknown ReturnNull.exe!ReturnNull.App.Main() C# [Native to Managed Transition] mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) Unknown Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() Unknown mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) Unknown mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() Unknown
Looks like issue was related to something in our local environment which requests accessibility access via the Automation Peers, (visible in the stack trace above).
Workaround is to disable this via code.
Thank you for your feedback.
I have been further investigating this. As you mention in your last post the issue comes from the automation client. It create a new automation peers. The grid uses cell`s value as part of default name of the cell`s automation peers, this is the reason that gets re-evaluated multiple times the getter. In the next service release will be available a static property NameSource. It will be part of the settings of CellAutomationPeer. You would be able to set it to DataItemAndFieldIndex. This will prevent the peer from accessing the value of the cell.
Please let me know if you need any further assistance on this matter.
Hello,
I am just checking your progress on the issue that you are having.
If you require any further assistance please do not hesitate to ask.