How to persist an Avalonia Geometry object? - avaloniaui

I'm getting an error trying to serialize an Avalonia.Media.Geometry object with Json.Net.
RectangleGeometry geometry = new RectangleGeometry(new Rect(32, 32, 32, 32));
string json = JsonConvert.SerializeObject(geometry);
gives
Self referencing loop detected for property 'Standardized' with type 'SkiaSharp.SKRect'. Path 'PlatformImpl.EffectivePath.Bounds'.
In WPF one can use string x = XamlWriter.Save(geometry);, but in Avalonia I can only find AvaloniaXamlLoader.
Does Avalonia have a WPF XamlWriter equivilent? Or perhaps some other method to persist a Geometry?

Related

Cannot serialize a string object with Microsoft.Bond

I am using Microsoft.Bond to serialize a class object which works perfectly fine. However, when I try to serialize a simple System.String object, the CompactBinaryWriter writes almost nothing to the output buffer. I am using this code:
string v = "test data";
var outputBuffer = new OutputBuffer();
var writer = new CompactBinaryWriter<OutputBuffer>(outputBuffer);
Serialize.To(writer, v);
var output = outputBuffer.Data;
output in this case is a one element array : {0}, irrespective of the value of v. Can someone point out why this doesn't work?
Bond requires a top-level Bond struct to perform serialization/deserialization.
If only one value needs to be passed/returned, the type bond.Box<T> can be used to quickly wrap a value in a Bond struct. (There's nothing special about bond.Box<T>, except that it ships with Bond.)
Try this:
Serialize.To(writer, Bond.Box.Create(v));
You'll need to deserialize into a bond.Box<string>.
There's an open issue about having better behavior in cases like this.

Confused by CaretOffset/LanguageItem methods

I am trying to find out over which source file element the cursor is located (code is inside a pad)
//Obtain document
Document sf = IdeApp.Workbench.ActiveDocument;
//out argument
DocumentRegion dr;
//Call using offset
Microsoft.CodeAnalysis.ISymbol o = sf.GetLanguageItem(sf.Editor.CaretOffset , out dr);
The ISymbol returned "o" is Object's Equals. The document sf is a simple class with a parameterless constructor. The cursor is inside the constructor. I was expecting my class constructor.
Where is the error?
Ok. I found a work around to get context data out of the current editor caret offset. It requires to obtain AnalysisDocument from the current document, then the SemanticModel of the document and after obtaining this model, calling GetEnclosingSymbol with the caret offset.

Populate picture box from eID vb.net

Hi i got form that reads eID card, smart cards
text data reads correctly
picturebox name is picLK
but last statement is a picture
in VB6 and VBA I used
me.pctLK.Picture = ReaderEngine.portrait
ReaderEngine is procedure that reads data from card
when I use command in vb.net I get an error
me.pctLK = ReaderEngine.portrait
reader is reading card, but I got this message
An unhandled exception of type 'System.InvalidCastException' occurred in Project1.exe
Additional information: Unable to cast COM object of type 'stdole.StdPictureClass' to class type 'System.Windows.Forms.PictureBox'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
I am new to VB .net
Is there any suggestions?
VB.NET has a helper function in the Microsoft.VisualBasic.Compatibility.VB6.Support module, named IPictureDispToImage, which accepts an StdPictureClass object (which implements IPictureDisp) and returns a .NET System.Drawing.Image object which you can assign to the PictureBox.Image property. Be sure you appropriately dispose of the Image when you're finished with it:
Dim comImage As StdOle.StdPictureClass = ReaderEngine.portrait
If Me.picLK.Image Is Not Nothing Then
Me.picLK.Image.Dispose()
Me.picLK.Image = Nothing
End If
Dim newImage As System.Drawing.Image = Support.IPictureDispToImage( comImage )
Me.picLK.Image = newImage

Creating WCF service by determining type at runtime

I am trying to create a WCF service without knowing its type/interface at runtime. To do this, I use ChannelFactory. ChannelFactory is a generic class so I need to use Type.MakeGenericType. The type I pass to MakeGenericType is from a list of interfaces I previously gathered with reflection by searching some assemblies.
Ultimately, I call MethodInfo.Invoke to create the object. The object is created just fine, but I cannot cast it to the proper interface. Upon casting, I receive the following error:
"Unable to cast transparent proxy to type 'Tssc.Services.MyType.IMyType'"
After some experimenting, I have found that the interface/type passed to MakeGenericType seems to be the problem. If I substitute the interface in my list with the actual interface, then everything works fine. I have combed through the two objects and cannot see a difference. When I modify the code to produce both types, comparing them with Equals returns false. It is unclear to me whether Equals is just checking that they are referring to the same object (not) or thety are checking all properties, etc.
Could this have something to do with how I gathered my interfaces (Reflection, saving in a list...)? A comparison of the objects seems to indicate they are equivalent. I printed all properties for both objects and they are the same. Do I need to dig deeper? If so, into where?
// createService() method
//*** tried both of these interfaces, only 2nd works - but they seem to be identical
//Type t = interfaces[i]; // get type from list created above - doesn't work
Type t = typeof(Tssc.Services.MyType.IMyType); // actual type - works OK
// create ChannelFactory type with my type parameter (t)
Type factoryType = typeof(ChannelFactory<>);
factoryType = factoryType.MakeGenericType(new Type[] { t });
// create ChannelFactory<> object with two-param ctor
BasicHttpBinding binding = new BasicHttpBinding();
string address = "blah blah blah";
var factory = Activator.CreateInstance(factoryType, new object[] { binding, address });
// get overload of ChannelFactory<>.CreateChannel with no parameters
MethodInfo method = factoryType.GetMethod("CreateChannel", new Type[] { });
return method.Invoke(factory, null);
//--------------- code that calls code above and uses its return
object ob = createService();
//*** this cast fails
Tssc.Services.MyType.IMyType service = (Tssc.Services.MyType.IMyType)ob;
Ok, I understand whats happening here - the problem is relating to loading the same assembly being effectively loaded twice - once via a reference, and once via the assembly load command. What you need to do is change the place where you load your assembly, and check to see if it already exists in the current AppDomain, like this maybe:
Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name.Equals("ClassLibrary1Name"));
if (assembly == null)
{
assembly = System.Reflection.Assembly.LoadFile("path to your assembly");
}
//do your work here
This way if the assembly is already loaded into memory, it'll use that one.

Stop WCF Deserializing Empty ICollection into Zero Capacity Array

I'm having a problem using WCF and Entity Framework 4.1 POCO objects (generated using T4 templates). My basic problem is that when sending a POCO object from my client to the service, WCF is deserializing a member variable of type ICollection as a fixed size array.
On the client side I can tell visual studio to use IList instead of T[] - but I cant see any option like this on the server end.
This causes no end of problems with several things, such as persisting these objects back to the database.
Is there any way to tell WCF what object type to deserialize ICollection (or any array) as?
I'm surprised that more folks haven't run into this issue, as it hits you smack in the face when you try to use the EF T4-generated POCO objects over WCF. Specifically, the error I was getting said something like:
Exception: "Unable to set field/property Orders on entity type Datalayer.Customers. See InnerException for details."
InnerException: "An item cannot be added to a fixed size Array of type 'Datalayer.Order[]'."
At any rate, the only solution I've been able to come up with is the one that you mention, namely, modifying the T4 templates to use HashSet instead of ICollection. Doesn't strike me as the cleanest, but it seems to work.
I'm using Entity Framework 6, and I was able to solve this issue by making the following changes in my T4 template.
I changed the following line where it creates the navigation properties to use a List instead of a collection from
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
to
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("List<" + endType + ">") : endType,
Then I changed the code that sets the navigation property in the constructor to convert the default hashset to a list by adding a call to .ToList(). This line
this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
was changed to
this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>().ToList();
The HashSet<>.ToList() method is an extension, so in order to make that extension method available, I added a using System.Linq statement by modifying the UsingDirectives method:
public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
? string.Format(
CultureInfo.InvariantCulture,
"{0}using System;{1}" + Environment.NewLine +
"{0}using System.Linq;" +
"{2}",
inHeader ? Environment.NewLine : "",
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
inHeader ? "" : Environment.NewLine,
Environment.NewLine)
: "";
}