Showing posts with label Exception. Show all posts
Showing posts with label Exception. Show all posts

Thursday, March 19, 2020

A TwoWay or OneWayToSource binding cannot work on the read-only property

I ran into an InvalidOperationException when binding to a read-only property in the model

I.e. my model looks something like this:
public class Customer
{
 public Guid Id { get; set; }
 public string Name { get; set; }
 public List Orders { get; set; }
 public double CalculatedProperty => Orders.Sum(x => x.TotalPrice);
}
And my binding in XAML something like:
{Binding CalculatedProperty, StringFormat='0.00'}

To get around this, we need to update the binding to set the Mode to something else then TwoWay or OneWayToSource, simplest is to just set it to OneWay like the following:
{Binding CalculatedProperty, StringFormat='0.00', Mode=OneWay}



Hope this helps someone out there!

Full exceptioon stack-trace
System.InvalidOperationException
  HResult=0x80131509
  Message=A TwoWay or OneWayToSource binding cannot work on the read-only property 'CalculatedProperty' of type 'Model.Entity.Customer'.
  Source=PresentationFramework
  StackTrace:
   at MS.Internal.Data.PropertyPathWorker.CheckReadOnly(Object item, Object info)
   at MS.Internal.Data.PropertyPathWorker.ReplaceItem(Int32 k, Object newO, Object parent)
   at MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange)
   at MS.Internal.Data.ClrBindingWorker.AttachDataItem()
   at System.Windows.Data.BindingExpression.Activate(Object item)
   at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
   at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(Boolean lastChance)
   at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance)
   at MS.Internal.Data.DataBindEngine.Run(Object arg)
   at MS.Internal.Data.DataBindEngine.OnLayoutUpdated(Object sender, EventArgs e)
   at System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
   at System.Windows.ContextLayoutManager.UpdateLayout()
   at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
   at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run()
   at UI.WPF.App.Main()

  This exception was originally thrown at this call stack:
 MS.Internal.Data.PropertyPathWorker.CheckReadOnly(object, object)
 MS.Internal.Data.PropertyPathWorker.ReplaceItem(int, object, object)
 MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(int, System.ComponentModel.ICollectionView, object, bool)
 MS.Internal.Data.ClrBindingWorker.AttachDataItem()
 System.Windows.Data.BindingExpression.Activate(object)
 System.Windows.Data.BindingExpression.AttachToContext(System.Windows.Data.BindingExpression.AttachAttempt)
 System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(bool)
 MS.Internal.Data.DataBindEngine.Task.Run(bool)
 MS.Internal.Data.DataBindEngine.Run(object)
 MS.Internal.Data.DataBindEngine.OnLayoutUpdated(object, System.EventArgs)
    ...
    [Call Stack Truncated]

Saturday, January 28, 2017

OpenGL various errors with shaders


This is my dump of easy fixes for problems that pop up from time to time. As I am quite the novice with both OpenGL and shaders, they do stop my progress quite so often. So hopefully this will help someone else who is googling for the solutions. :)
I guess that this list will grow over time.

For more on OpenGL, look up my tutorial series starting with:
OpenGL 4 with OpenTK in C# Part 1: Initialize the GameWindow

error C7565

0(18) : error C7565: assignment to varying 'tes_out'
Check that tes_out actually is declared as out. Copying from previous shader one might forget to change it to in in the next.

error C1035

0(18) : error C1035: assignment of incompatible types
Example of faulty code.
in TCS_OUT
{
   vec4 color;
} tes_in[];
out TES_OUT
{
   vec4 color;
} tes_out;
void main(void)
{
   /* threw error */
   tes_out = tes_in[0];
   /* fixed, uncomment */
   /* tes_out.color = tes_in[0].color; */
}

Other errors could be assignment of a vec3 to a vec4.

error C3008

0(4) : error C3008: unknown layout specifier 'max_vertices = 3'
0(4) : error C3008: unknown layout specifier 'points'
I had loaded an geometry shader, but told OpenGL that it was an Tesselation Evaluation Shader, so changing the type to the correct one solved it.

error C3004

0(22) : error C3004: function "void EmitVertex();" not supported in this profile
I had loaded an geometry shader, but told OpenGL that it was an Tesselation Evaluation Shader, so changing the type to the correct one solved it.

error C1048

0(14) : error C1048: invalid character 'Y' in swizzle "Y"
This one was tricky, turned out that all vecX are referenced by lower case letters. Error message was from when trying to reference with upper case. Or any other non-existent letter
vec4 color;
color.A // this is wrong
color.a // this is right



Program linking warning

warning:  two vertex attribute variables (named position and color) were assigned to the same generic vertex attribute
Just as described, had set the location of two attributes to the same (0), solved by assigning correct location i.e. 0 and 1 in this case.
layout (location = 0) in vec4 position;
layout(location = 0) in vec4 color;

Addition of Tessellation Control Shader and Tessellation Evaluation Shader results in black screen

Works fine when running only Vertex Shader and Fragment Shader, but when adding Tesselation, it just stops working. Took me 3 hours of trying to understand what I missed in the examples until I found that if you use Tesselation, you need to change from Triangles to Patches. 
GL.DrawArrays(PrimitiveType.Patches, 0, 3);

OpenTK GL.CompileShader System.AccessViolationException was unhandled


Tried to add another shader (Tesselation Control Shader this time) to my program and received the following exception when compiling it with GL.CompileShader
System.AccessViolationException was unhandled
  HResult=-2147467261
  Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
  Source=OpenTK
  StackTrace:
       at OpenTK.Graphics.OpenGL4.GL.CompileShader(Int32 shader)
       at techdump.opengl.Components.MainWindow.CompileShaders() in C:\tfs\techdump\techdump\techdump.opengl\Components\MainWindow.cs:line 58
       at techdump.opengl.Components.MainWindow.OnLoad(EventArgs e) in C:\tfs\techdump\techdump\techdump.opengl\Components\MainWindow.cs:line 38
       at OpenTK.GameWindow.Run(Double updates_per_second, Double frames_per_second)
       at techdump.opengl.Program.Main() in C:\tfs\techdump\techdump\techdump.opengl\Program.cs:line 11
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

So what went wrong? Looking at the variables in the debug I see that the shader was loaded correctly from the file, GL.ShaderSource did not complain.
Been trying to read up on this for the last hour but no luck.

Last resort. As I am on a laptop and have both an Intel(R) HD Graphics 530 chip and a NVIDIA GeForce GTX 960M, I try to switch and start with the NVidia instead. And it works.

To try this, open up your build folder in windows explorer, right click and select, run with graphics processor and then select your NVidia card.
Turns out that NVidia tries to save energy and starting things with the Intel chip if its not a game. Good for battery life, less so for games development :)
This also turns out to solve the issue with version compatibility from a previous post where the work around was to use an older version of OpenGL.

So how to setup so that your visual studio runs with the correct GPU as default?

This seems to be harder than I imagined. But thanksfully there is a solution to this over at drivenbynostalgia.com. Basically they provide a class that you add to your application that registers it with your NVidia drivers and states that it is a game. So go to their site and find the 'sop - setoptimusprofile' section.


Also to note, the SOP solution is x86 only. I got the following exception when trying to run it in 64-bit mode.

System.TypeLoadException was unhandled
  HResult=-2146233054
  Message=Could not load type 'Setting' from assembly 'techdump.opengl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field.
  Source=techdump.opengl
  TypeName=Setting
  StackTrace:
       at techdump.opengl.Components.SOP.SOP_SetProfile(String profileName, String applicationName)
       at techdump.opengl.Program.HandleSop() in C:\tfs\techdump\techdump\techdump.opengl\Program.cs:line 21
       at techdump.opengl.Program.Main() in C:\tfs\techdump\techdump\techdump.opengl\Program.cs:line 12
  InnerException: 

So no x64. So I had to go back to 32 bits. I guess I can live with that :)

Update 2017-01-28
Seems that if you do not close the program correctly X times, the above exception starts throwing again. Trying to start it with Intel chip this time works. After a reboot the NVidia chip works as well.. The OpenTK override Exit does not seem to trigger if you close the window manually. Can be solved by adding following event handler to your OnLoad override.
protected override void OnLoad(EventArgs e)
{
    /// other init code
    Closed += OnClosed;
}

private void OnClosed(object sender, EventArgs eventArgs)
{
    Exit();
}


Hope this helps someone out there :)

Saturday, October 22, 2016

Foreign Key constraint issue, hard to find cause

This hard to figure out issue has popped up from time to time

The DELETE statement conflicted with the REFERENCE constraint "FK_Order_Customer".
The conflict occurred in database "DATABASE", table "dbo.Order", column 'CustomerID'.

Not so much to do with the actual execution of your program, it works for most data but it seems that if a co-worker has manually edited data in the database with Sql Management Studio, there is a possibility that an extra line-break is introduced if the user confirms her edit with the return button.

To find the issue, copy the data and paste it to your favorite text-editor, in between two quotation marks.
Correct data:
'data'
Bad data:
'data
'
Remove the extra line break and you should be good to go.

Of course, good database design should prevent this from happening but sometimes you are stuck with legacy systems and it is good to know that this can happen, especially if you have people manually editing data in the database.

Hope this helps someone out there :)

Saturday, October 8, 2016

WinForms RichTextBox Append Log and UIThread extensions

Turn any RichTextBox in winforms to a log view. Just call rtxt.AppendLog("someString"); and it will append that to a new line in the richtextbox. And scroll it to view.

public static void AppendLog(this RichTextBox rtxt, string s)
{
 rtxt.UIThread(() =>
 {
  rtxt.AppendText($"{s}{Environment.NewLine}");
  rtxt.SelectionLength = 0;
  if (rtxt.Lines.Length > 10000)
  {
   rtxt.Lines = rtxt.Lines.Skip(5000).ToArray();
  }
  rtxt.SelectionStart = rtxt.TextLength;
  rtxt.ScrollToCaret();
 });
}
The above snippet of code requires the following to function correctly.
static public void UIThread(this Control control, Action code)
{
 if (control.InvokeRequired)
 {
  control.BeginInvoke(code);
  return;
 }
 code.Invoke();
}
I can't take credit, found it years ago on some forum somewhere. But here it is anyway. It makes a call to a winforms control synschronize with the GUI thread so that no cross-threading exceptions is thrown. GUI items can only be modified from the GUI thread and this ensures just that.

The exception thrown if correct thread synchronization is not used is: 
System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Cross-thread operation not valid: Control 'rtxtOutput' accessed from a thread other than the thread it was created on.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.Control.get_Handle()
       at System.Windows.Forms.TextBoxBase.GetSelectionStartAndLength(Int32& start, Int32& length)
       at System.Windows.Forms.TextBoxBase.set_SelectionLength(Int32 value)
       at System.Windows.Forms.RichTextBox.set_SelectionLength(Int32 value)
       at ave.dev.winform.Form1.ticker_Tick(Object sender, EventArgs e) in C:\tfs\YYY\Form1.cs:line 54
       at ave.dev.winform.Form1._loggerHook_NewLogLine(String s) in C:\tfs\YYY\Form1.cs:line 38


Back to extensions list