Reflection error when using F# sprintf "%A" on Windows Phone - silverlight

I have a set of F# record types like this:
type Course =
{ Id : int
Title : string
Instructor : string
Duration : string
StartDate : string
IconUrl : string
Url : string
LectureSections : LectureSection list }
and LectureSection =
{ Title : string
Completed : bool
Lectures : Lecture list }
and Lecture =
{ Title : string
VideoUrl : string }
and at some point I call
sprintf "%A" course
where course is an instance of the Course record
On a regular .NET project this works fine, but on a Windows Phone 7.1 / Silverlight 4 F# project (I'm using Daniel Mohl's templates), I get this error:
Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.
The problem seems to be the lists. Does anyone know of any way around this problem?

The templates should come with a custom built FSharp.Core.dll that disable features that are not available on Windows Phone. Are you sure you are compiling against this dll, and not the Windows PC one?
I had similar problems with Xbox360 and XNA. The F# team sent me a dll suitable for use for the Xbox360, along with some brief instructions on the settings used to build the dll.
Here is the propertygroup we've used to compile FSharp.Core:
<PropertyGroup Condition="'$(TargetFramework)'=='Xbox360\CompactFramework\3.7'">
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
<XnaPlatform>Xbox 360</XnaPlatform>
<XnaProfile>HiDef</XnaProfile>
<XnaCrossPlatformGroupID>a8d70e6b-9a75-4aec-80f8-62cf373f7368</XnaCrossPlatformGroupID>
<XnaOutputType>Game</XnaOutputType>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<DefineConstants>$(DefineConstants);FX_NO_ARRAY_LONG_LENGTH;FX_NO_DEBUG_PROXIES;FX_NO_EXIT;FX_FSLIB_IOBSERVABLE;FX_NO_WEB_CLIENT;FX_NO_WEB_REQUESTS;FX_NO_CHAR_PARSE;FX_NO_DEFAULT_DEPENDENCY_TYPE;FX_SIMPLE_SECURITY_PERMISSIONS;FX_NO_TRUNCATE;FX_NO_CULTURE_INFO_ARGS;FX_NO_REFLECTION_MODULE_HANDLES;FX_NO_OPERATION_CANCELLED;FX_NO_TO_LOWER_INVARIANT;FX_NO_EXIT_CONTEXT_FLAGS;FX_NO_BASED_ARRAYS;FX_NO_DOUBLE_BIT_CONVERTER;FX_NO_BINARY_SERIALIZATION;FX_NO_ASCII_ENCODING;FX_NO_DEFAULT_ENCODING;FX_NO_FILE_OPTIONS;FX_NO_NONBLOCK_IO;FX_NO_COMMAND_LINE_ARGS;FX_NO_ENVIRONMENT;FX_NO_PROCESS_START;FX_NO_APP_DOMAINS;FX_NO_PROCESS_DIAGNOSTICS;FX_FSLIB_STRUCTURAL_EQUALITY;FX_FSLIB_LAZY;FX_FSLIB_TUPLE;FX_NO_REFLECTION_EMIT</DefineConstants>
<Tailcalls>false</Tailcalls>
<!-- It would be better to use MSBuild resolution here, but the TargetFrameworkIdentifier etc. aren't set up quite correctly as yet -->
<OtherFlags>$(OtherFlags) --simpleresolution -r:"C:\Program Files\Microsoft XNA\XNA Game Studio\v4.0\References\Xbox360\mscorlib.dll"</OtherFlags>
</PropertyGroup>
and the new .targets we use:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" Condition="'$(TargetFramework)'=='Xbox360\CompactFramework\3.7'"/>
The dll they sent me was working fine, and I never had to use these instructions, but they might be useful to someone who wants to build an FSharp.Core.dll for a new platform. Note in particular the DefineConstants part.

Related

Cannot Browse to specific Type in Settings designer for WPF/.net Core application

When I've used Settings Designer before, I've been able to browse to find non-standard Types (e.g. uncommon enums etc) to use in my Settings via a "Browse" button at the bottom of the drop down under the "Type" column. I'm developing a WPF desktop application for .net Core and there is no Browse option as pictured below:
I did go into the code behind (Settings.Designer.cs.) and edit the code manually, but on saving, this just reverted to string. I'm guessing this may have something to do with settings also having an element in App.config and I notice it has a "serialiseAs" tag - didn't know what to put here. Exmaple of the code behind settings and App.config:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string UiTheme {
get {
return ((string)(this["UiTheme"]));
}
set {
this["UiTheme"] = value;
}
}
<userSettings>
<GameBoxer.WPF.Properties.Settings>
<setting name="UiTheme" serializeAs="String">
<value />
</setting>
</GameBoxer.WPF.Properties.Settings>
</userSettings>
Does anyone know how to bring back the 'Browse'?? Or, how to correctly do it in code?
I'm using Visual Studio 2022 Community
Thanks
UPDATE: So, I learn that this is "By Design" in VS2022 according to MS here. It's still present in VS2019! But they've taken it out of VS2022 and I can't figure how to do it in code. MS, you're one of my faves out the bunch, but sometimes, you're as mad as a box of frogs. unfortunately that link doesn't provide the poster with any alternatives other than "that's not a bug." Not very helpful, really.
As mentioned in the link you provided, this change was by design due to .NET Core and while I very strongly disagree with their stance on this - I'm assuming this was done because it could be quite fiddly to get your own types to work as expected, especially for new users.
One simple workaround if your custom data has several values, you can use string and simply write your own little parser using delimiters such as ;. You could also use StringCollection to achieve the same result.
Inconvenient, yes. But a simple solution nonetheless.
I sincerely hope Microsoft changes their stance on this and looks at reimplementing this as it worked remarkably well once you figured out the procedure to get it to serialize properly.
Edit:
Figured I might as well provide an example;
// Storing the Settings
// Parameter: Struct { Location(Point), Size(Point), Margin(Thickness) }
var settingString = $"{e.Location.X};{e.Location.Y};{e.Size.X};{e.Size.Y};{e.Margin.Left};{e.Margin.Top};{e.Margin.Right};{e.Margin.Bottom}";
Properties.Settings.Default.MySetting = settingString;
Properties.Settings.Default.Save();
// Parsing the Saved Setting
var settingString = Properties.Settings.Default.MySetting;
if (!String.IsNullOrWhiteSpace(settingString))
{
List<string> splitStrings = settingString.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList();
List<double> parsedValues = new List<double>();
splitStrings.ForEach(x => parsedValues.Add(double.Parse(x)));
var location = new Point(parsedValues[0], parsedValues[1]);
var size = new Point(parsedValues[2], parsedValues[3]);
var margin = new Thickness(parsedValues[4], parsedValues[5], parsedValues[6], parsedValues[7]);
}
There's probably better ways of doing this, but I find this to be a very simple workaround and has worked great thus far.

Could not find the reference to GUID_DEVINTERFACE_NET class

I am using MS VS2008 to build my application. I need to use "GUID_DEVINTERFACE_NET " class to get the device interface list. But i could not find the reference to this class. I have even tried in MS VS2015 but could not the reference.
Below is the code snippet.
ULONG DeviceListLength = 0;
cr = CM_Get_Device_Interface_List_SizeW(&DeviceListLength,
(LPGUID)&GUID_DEVINTERFACE_NET,
NULL,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
The Microsoft online documentation is not very detailed, but it does mention the header file Ndisguid.h. The filename might use a different case, but the Windows file system is not case-sensitive anyway:
#include <ndisguid.h>
references:
https://msdn.microsoft.com/en-us/library/windows/hardware/ff545922(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/hardware/ff538471(v=vs.85).aspx

Can't find file with UserControl but not (in this case) Label

I have a UserControl in a the DLL Controls, a converter in the DLL Base and language resources in the DLL Languages.
When I combine everything the following way, everything works fine:
<Label Content="{Binding FallbackValue='[Design] Name', ConverterParameter='Name', Converter={StaticResource Translate}}"
ContentStringFormat="{}{0}:"/>
No errors and when I run my application the correct word for the parameter Name is loaded (in my case Naam for Dutch).
I also try this on my WatermarkTextBox like this:
<c:WatermarkTextBox Watermark="{Binding FallbackValue='[Design] Name *', ConverterParameter='Name', Converter={StaticResource Translate}}" />
But then I get the following error:
Could not load file or assembly 'file:///C:...\Languages.dll' or one of its dependencies. The system cannot find the file specified.
Why does this happen with my WatermarkTextBox in Controls DLL and not with the Label?
The first step here is to make sure, that the assembly file Languages.dll is actually present in the application directory (usually, bin/Debug/). If it isn't - as the error message says - the system cannot find the file specified... The solution in this case is to reference the assembly Languages.dll in your application project. To avoid this, make sure that every time you add a reference to an assembly, you also add references to this assembly's dependencies. I.e. if you have an application project App which references a library LibA.dll and LibA references a library LibB.dll, you should add a reference to LibB.dll in your App project as well. That way, all required assemblies will always be copied to the output directory.
If the assembly is correctly located in the output directory, but you still get the error message, in 99% of the cases the problem is a mismatch in the building targets, alas the platform for which the assemblies were built. Make sure all projects target the same platform (x86, for example). You can check the target in the projects Properties tabs.
EDIT:
Ok, I just now understood you're talking about the design time error in Visual Studio's XAML Designer :) The issue is the name of the assembly: Noru.Languages.dll. I suppose, the ending .Languages is considered a resource name and Visual Studio prohibits resource names in assembly names. There's a registry entry HKLM\Software\Microsoft\VisualStudio\12.0\Designers\AllowResourcesInFilename, maybe experimenting with that can resolve the issue. Not 100% sure, though. Anyway, if you rename the assembly to Nori.Language.dll in the project's properties and rebuild everything, design time support is back and the controls show up correctly in the designer.
EDIT 2:
Really strange behavior altogether... Well, this line in the Class Language might very well be the cause? Try specifying the full string here... Does this work?
ResourceManager rm = new ResourceManager("Noru.Languages.Language", System.Reflection.Assembly.LoadFrom("Noru.Languages.dll"));
EDIT 3:
Obviously, the problem was the line I mentioned above in Edit 2. I've experimented a bit:
/// <summary>
/// Will return the requested text in the language the application is in. Case sensitive.
/// </summary>
/// <param name="s">Provide a listed String from the language files.</param>
/// <returns>Will return a System.String in the language of the application.</returns>
public static string GetText(string s)
{
//return Culture.ToString();
//return Assembly.GetExecutingAssembly().FullName;
//ResourceManager rm = new ResourceManager("Noru.Lang.Resource1", Assembly.GetAssembly(typeof(Language)));
//ResourceSet rs = rm.GetResourceSet(Culture, true, true);
var rs = LanguageResource.ResourceManager;
try
{
return rs.GetString(s);
}
catch (Exception)
{
return "not found";
}
}
The last version (not commented out) works, because I've generated code for the resource files by setting AccessModifier to public in the resource editor (double click on the resource file, you'll find it in the toolbar).
This version (never mind about the resource name, I tried different versions here):
ResourceManager rm = new ResourceManager("Noru.Lang.Resource1", Assembly.GetAssembly(typeof(Language)));
threw another error, saying it cannot find the resource inside the assembly. I think there was something wrong about the usage of ResourceManager here. I'm not an expert here, so I can't tell why. I just know that the last version seems to work as expected... I hope, you'll find the same ;)

F# quotations on Windows Phone

I'm using Daniel Mohl's F# templates for Windows phone, but it seems the bundled FSharp.Core doesn't have some of the quotations code. I'm trying to port this code from regular .NET:
open System.ComponentModel
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
[<AbstractClass>]
type ViewModelBase() =
let propertyChanged = new Event<_, _>()
let toPropName expr =
match expr with
| PropertyGet(a, b, list) -> b.Name
| _ -> failwith "Unsupported: " + expr.ToString()
interface INotifyPropertyChanged with
[<CLIEvent>]
member x.PropertyChanged = propertyChanged.Publish
member x.NotityPropertyChanged expr =
propertyChanged.Trigger(x, new PropertyChangedEventArgs(toPropName expr))
But the compiler complaints about Microsoft.FSharp.Quotations.Patterns and PropertyGet. It seems it doesn't even know the Expr type.
Any idea on how to solve this?
I replaced the FSharp.Core file that comes in the template by the one that comes in the F# April 2011 CTP in the WindowsPhone7\Silverlight\4.0\bin folder, and with this version it now compiles fine
I've compared FSharp.Core.dll from Template you've mentiond and those one which is referenced if you create a F# Silverlight library with .Net Reflector and they are different! :) Thouse one which added to template's dependencies folder doesn't have Quotations.
So my first two thoughts is either add F# SCL and create your view model there or not to use this template at all. But I actually like this template or how it looks at least... so thanks you for the mentioning it anyway :)

How-to: Load a type from a referenced assembly at runtime using a string in Silverlight

I have tried this, specifying the assembly name:
Type.GetType(string.Format("{0}.{1}, {0}", typeToLoad.AssemblyName, typeToLoad.ClassName));
Which throws the following:
The requested assembly version conflicts with what is already bound in the app domain or specified in the manifest
Trying the same without including the trailing assembly name like this:
Type.GetType(string.Format("{0}.{1}", typeToLoad.AssemblyName, typeToLoad.ClassName));
-- returns null.
So, I am looking for a way to instantiate a class by providing its fully qualified name in Silverlight 4.0.
Any ideas would be greatly appreciated, Thanks.
I had the same issue and it worked when I tried the assembly qualified type name in the following format :
", , Version="", Culture=, PublicKeyToken="

Resources