I'm studying Uno platform, and I would like to write my platform specific code in separate assemblies without using #if statements. I googled this link where they suggest using partial classes. Works fine but then I'd like to swap FrameworkElement depending on a platform. I followed this tutorial and this one and got this code for WASM head that is located in .Shared project:
[HtmlElement("input")] // Flatpickr requires an <input> HTML element
public partial class FlatpickrView : FrameworkElement
{
// *************************
// * Dependency Properties *
// *************************
public static readonly DependencyProperty SelectedDateTimeProperty = DependencyProperty.Register(
"SelectedDateTime", typeof(DateTimeOffset?), typeof(FlatpickrView), new PropertyMetadata(default(DateTimeOffset?)));
public DateTimeOffset? SelectedDateTime
{
get => (DateTimeOffset)GetValue(SelectedDateTimeProperty);
set => SetValue(SelectedDateTimeProperty, value);
}
//rest of the properties
}
To keep this code explicitly just for WASM I moved this file to .WASM project and added empty stub in .Shared project:
namespace FlatpickrDemo
{
public partial class FlatpickrView : FrameworkElement
{
}
}
But the result is that when I'm starting project with WASM head no JavaScript is executed.
How do I effectively swap Control or Elements depending on a platform while keeping code in its respective head?
Related
I have a Xamarin based Visual Studio 2015 project that has the following structure.
MyApp (Portable)
MyApp.Droid
MyApp.iOS
Currently I include assets / resources in the MyApp.Droid project and the MyApp.iOS project.
So for example myhtml.html is duplicated as both MyApp.Droid/Asserts/myhtml.html and MyApp.iOS/Resources/myhtml.html
Are there any ways I can avoid this duplication?
Assuming you are using Xamarin Forms, yes, you can use .net resource files.
You can create a folder in the portable project, add there the content files and set the Compilation Action to Embedded Resource for all of those, then you can use the .net provided mechanism to acces the resources, per example (in this example I assume the code is being executed in a class contained in the portable project and the files are stored in a folder called ResourceFiles):
var htmlFile = this.GetType().GetTypeInfo().Assembly.GetManifestResourceStream("MyNamespace.ResourceFiles.myhtml.html");
In this way you have the stream with the file's content.
Also, as a hint, you can load these files from XAML using a custom markup extension, per example, here is a markup extension to load images from .net resources:
[ContentProperty ("Source")]
public class ImageResourceExtension : IMarkupExtension
{
public string Source { get; set; }
public object ProvideValue (IServiceProvider serviceProvider)
{
if (Source == null)
return null;
var imageSource = new StreamImageSource { Stream = async (ct) => this.GetType().GetTypeInfo().Assembly.GetManifestResourceStream(Source) };
return imageSource;
}
}
Then, to use this extension in XAML you will do (local is the XAML namespace definition of your own namespace):
<Image Source="{local:ImageResource MyNamespace.ResourceFiles.MyImage.png}" />
First thing I must say is that I'm not really sure about how to phrase this questions since I'm new to Xamarin.
I'm building an app in Xamaring with the aim of being Cross Platform.
These are the steps:
Create Solution
New Project, name: Demo.UI.TestHarness.iOS, type: iOS Unified Unit Test App
New Project, name: Demo.UnitTests, type: Cross-Platform Portable Library
Make Demo.UI.TestHarness.iOS the startup project
Add Nuget package NUnitLite to Demo.UnitTests
Add Reference to Demo.UnitTests in Demo.UI.TestHarness.iOS
This done, I created a class DummyTest in Demo.UnitTests:
using System;
using NUnit.Framework;
namespace Demo.UnitTests
{
[TestFixture]
public class DummyTest
{
[Test]
public void DUMMY ()
{
Assert.True (false);
}
}
}
And I added to the file UnitTestAppDelegate in Demo.UI.TestHarness.iOS a reference to this DummyTest:
using System;
using System.Linq;
using System.Collections.Generic;
using Foundation;
using UIKit;
using MonoTouch.NUnit.UI;
using Demo.UnitTests;
namespace Demo.UI.TestHarness.iOS
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register ("UnitTestAppDelegate")]
public partial class UnitTestAppDelegate : UIApplicationDelegate
{
// class-level declarations
UIWindow window;
TouchRunner runner;
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// create a new window instance based on the screen size
window = new UIWindow (UIScreen.MainScreen.Bounds);
runner = new TouchRunner (window);
// register every tests included in the main application/assembly
// runner.Add (System.Reflection.Assembly.GetExecutingAssembly ());
runner.Add(typeof(DummyTest).Assembly);
window.RootViewController = new UINavigationController (runner.GetViewController ());
// make the window visible
window.MakeKeyAndVisible ();
return true;
}
}
}
Now, I can build the project and run the debugger simulation, but no tests show up.
If instead I add the DummyTest directly inside my Demo.UI.TestHarness.iOS project and completely forget about the Demo.UnitTests project, it runs as intended (but this is not what I want because I want to make the tests all together to later use the same tests for Android and Mac and not having to redo them for every platform).
Incase anyone else is wondering why this does not work - here is what my research led me to:
https://forums.xamarin.com/discussion/16909/cant-test-pcl-test-assembly-from-xamarin-android-nunitlite-or-monotouch-nunit-ui
Specifically the post by "Seb Bartholomew". In his reply he posts a work around (which I have not tried yet). The basic issue is:
Xamarin.iOS uses MonoTouch.NUnitLite, Xamarin.Android uses Xamarin.Android.NUnitLite and the PCL used the base NUnit nuget package.
Although the assemblies have the same names and belong to the same namespaces they are intact different types so the Monotouch test runner does not detect the external [Test] attributes.
I am going through some WPF example I found.
I have a class here which is inherited from Application:
public partial class DataBindingLabApp : Application
{
private ObservableCollection<AuctionItem> auctionItems = new ObservableCollection<AuctionItem>();
public ObservableCollection<AuctionItem> AuctionItems
{
get { return this.auctionItems; }
set { this.auctionItems = value; }
}
}
As you can see this class have a property called AuctionItems.
Because it inherits from Application it also contains property called 'Current' which provides access to the Application instance (according to MSDN).
Then in the code I have:
((DataBindingLabApp)Application.Current).AuctionItems.Add(item);
I do not understand it.
Since we can have many classes which may inherit from Application then how we know that Application.Current actually contains object of class 'DataBindingLabApp'?
Thank you!
Because Visual Studio generates entry point in the partial generated class of custom application type(DataBindingLabApp in your case) by default (You can find it by searching in the root directory of solution).
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main() {
DataBindingLabApp app = new DataBindingLabApp();
app.InitializeComponent();
app.Run();
}
And after application has been ran Application.Current contains instanse of DataBindingLabApp.
Since we can have many classes which may inherit from Application
That isn't relevant. What matters is that there is only ever one instance of the Application class. The one-and-only application that's running. Be sure to distinguish types from objects.
I am not a seasoned pro at C# and am running into an error I cannot find a discrete solution to. Currently I have one class that is part of my namespace
namespace BlackBoxStudio
{
public partial class Project : Form
{
This Project class is what implements the various functions of my form. What I am trying to do is make a label.text field accessable to another .cs class within the same namespace. As so, I have made the corresponding fields public:
public string lb_InformationText
{
get { return lb_Information.Text; }
set { lb_Information.Text = value; }
}
To call these I get or set methods in my RsaFunctions class I make a new private project as so:
namespace BlackBoxStudio
{
class RsaFunctions
{
//private Project proj = new Project();
However the line that is commented our causes my vshost32.exe application to fail and the program dies. Why is this causing the vshost32.exe to fail when I un-comment the corresponding line? Or how could I better structure my classes so this does not happen? Any tips would be much appreciated about my strategy for making new classes and such.
I have a question about how the .NET framework (2.0) resolves dependent assemblies.
We're currently involved in a bit of a rewrite of a large ASP.NET application and various satellite executables. There are also some nagging problems with our foundation classes that we developed a new API to solve. So far this is a normal, albeit wide-reaching, update.
Our heirarchy is:
ASP.NET (aspx)
business logic (DLLs)
foundation classes (DLLs)
So ASP.NET doesn't throw a fit, some of the DLLs (specifically the foundation classes) have a redirection layer that contains the old namespaces/functions and forwards them to the new API. When we replaced the DLLs, ASP.NET picked them up fine (probably because it triggered a recompile).
Precompiled applications don't though, even though the same namespaces and classes are in both sets of DLLs. Even when the file is renamed, it complains about the assemblyname attribute being different (which it has to be by necessity). I know you can redirect to differnet versions of the same assembly, but is there any way to direct to a completely different assembly?
The alternatives are to recompile the applications (don't really want to because the applications themselves haven't changed) or recompile the old foundation DLL with stubs refering to the new foundation DLL (the new dummy DLL is file system clutter).
You want to move the types to a new assembly? You can do that with [TypeForwardedTo(..)].
If you originally have (AssemblyA):
namespace SomeNamespace {
public class SomeType {}
}
You can instead move that type into AssemblyB, and have a virtually empty AssemblyA which references AssemblyB and simply contains:
[assembly: TypeForwardedTo(typeof(SomeNamespace.SomeType))]
Then anything trying to load SomeNamespace.SomeType from AssemblyA actually gets the type from AssemblyB.
Most of the runtime respects this attribute... everything except WCF extensions. Which bit me ;-p Oh, and it isn't a fan of nested types...
//File: RKAPPLET.EXE
namespace RKAPPLET
{
using RKMFC;
public static class Program
{
public static void Main ()
{
RKMFC.API.DoSomething();
}
}
}
//File: RKMFC.DLL
namespace RKMFC
{
public static class API
{
public static void DoSomething ()
{
System.Windows.Forms.MessageBox.Show("MFC!")
}
}
}
//File: RKNET.DLL
namespace RKNET
{
public static class API
{
public static void DoSomethingElse ()
{
System.Windows.Forms.MessageBox.Show("NET!")
}
}
}
namespace RKMFC
{
public static class API
{
public static void DoSomething ()
{
RKNET.API.DoSomethingElse()
}
}
}
I want RKAPPLET.EXE, compiled with RKMFC.DLL, to find RKNET.DLL (which has a copy of everything in RKMFC.DLL and then some) without recompiling either RKAPPLET.EXE (to point to it) or RKMFC.DLL (to redirect types).
Did you try adding <assemblyBinding> setting to config file ?
http://msdn.microsoft.com/en-us/library/twy1dw1e.aspx