So I have simple F# WPF application. It was working just fine without declaring a namespace and using multiple modules.
Now, it still compiles, but simply does nothing. Nothing in debug to show either.
This is the current code that does not work.
namespace Flow
module MainApp =
open System
open System.Windows
let app1 = new Application()
[<STAThread>]
app1.Run(new Main.MainWindow()) |>ignore
before it worked when it was like this
module MainApp
open System
open System.Windows
let app1 = new Application()
[<STAThread>]
app1.Run(new Main.MainWindow()) |>ignore
I can show the definition of MainWindow, but its very long, its a class that inherits from Window.
Let me know if that would help. Or if there is anything other information that I could give that would help with this issue.
Your original code relies on an implicit entry point:
"When a program has no EntryPoint attribute that explicitly indicates the entry point, the top level bindings in the last file to be compiled are used as the entry point."
You can either define a function in your module and explicitly mark that as the entry point:
namespace Flow
module MainApp =
open System
open System.Windows
let app1 = new Application()
[<EntryPoint>]
[<STAThread>]
let main args =
app1.Run(new Window())
Or you can continue to use an implicit entry point by including the namespace in the module name:
module Flow.MainApp
open System
open System.Windows
let app1 = new Application()
[<STAThread>]
app1.Run(new Window()) |>ignore
Related
I have a .netcoreapp3.1 Console App
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWpf>true</UseWpf>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
</Project>
In Program.fs, I am instantiating a WebBrowser control and handling the DocumentCompleted event
let run() =
let uri = "https://www.microsoft.com"
let browser = new WebBrowser()
browser.DocumentCompleted.Add(fun _ -> handlePage browser uris)
browser.Navigate(uri)
[<STAThread>]
[<EntryPoint>]
let main argv =
run()
Console.ReadKey() |> ignore
0
When I run it, the DocumentCompleted event is never fired or handled - the program runs through to the end.
Am I missing?
Thanks in advance.
Am I missing?
The message pump. You need a Dispatcher to run a WPF app.
On another note, you're using the WinForms WebBrowser, that one exposes the DocumentCompleted event. The WPF variant has the LoadCompleted event, ref this post.
In WPF, however, the concept of Loaded is related to the visual tree. As you're not rendering the control, the event will never be raised. If we instead use the Navigated event, we can get there with minimal fuss.
open System
open System.Windows
open System.Windows.Controls
type BrowserApplication() =
inherit Application()
let run() =
let uri = "https://www.microsoft.com"
let browser = new WebBrowser()
browser.Navigated.Add(fun _ -> Console.WriteLine("Done navigating"))
browser.Navigate(uri)
do run();
[<EntryPoint;STAThread>]
let main argv =
BrowserApplication().Run()
We have a DNN module that uses Angular as its client side framework.
I'd like to be able to embed all the resources such as html , js ,css ,images and fonts to my module.(actually our module have more than one dll and every one of them has its own resources so that I don't want to copy all of these resource into main module folder every time I want to make a package)
So far I have tried WebResource.axd which was successful to some extent (Here's what I have done)but then I realized that It is somehow impossible to embed html,images and other stuffs rather than js and css (or it isn't?)
Then I decided to try using VirtualPathProvider and I used this open source project that implements an EmbeddedResourcesVirtualProvider.
I have registered this provider using IRouteMapper interface of DNN. Now that I start testing my project I am getting 404 for all of my resources. I tried to debug the project and put some break points over FileExists ,DirectoryExists and GetFile methods of VirtualProvider but the only virtual path that is being asked from VirtaulProvider is "~/Default.aspx" and nothing else
I would like to ask if it is possible to use VirtualParhProvider with DNN ?
We are using DNN 8.
I think you are over complicating things a bit. If you need a virtual provider for your module to work you are doing it wrong (in my opinion).
A module should be a self-contained package that could be deployed on any DNN installation without having to do anything but install the module.
Normally when you buy or download a free module, it comes in a single zip file with all the necessary files contained in that zip. That could be any type of file (.dll, .js, css, .ascx, .aspx etc) is does not matter as long as it's defined in the .dnn installation file.
You can then link to the files in the ascx of your module.
<script type="text/javascript" src="/DesktopModules/YourModulePath/js/file.js"></script>
or
<img src="/DesktopModules/YourModulePath/images/image.jpg">
With WebResource you can embed anything - images, html, fonts etc., so I would suggest continuing with the approach you've already taken.
I downloaded and installed your module in DDN 8 for testing. So the following assumes that setup.
To embed an image you can do this:
In the library MyFramework:
Add a file called image.png to a new folder \content\images\
Set Build Action to Embedded Resource for this image
Add [assembly: System.Web.UI.WebResource("MyFramework.content.images.image.png", "image/png")] to AssemblyInfo.cs
Add protected string myImageUrl { get; private set; } so we can access the URL in the inheriting class
Add myImageUrl = Page.ClientScript.GetWebResourceUrl(typeof(MyModuleBase), "MyFramework.content.images.image.png"); to your OnInit() method
In the consuming project MyModule:
Add <img src="<%=myImageUrl%>"/> to View.ascx
For HTML and similar content type, you can do basically the same as you have already done for the scripts:
In the library MyFramework:
Add a file called myhtml.html to a new folder \content\html\
(in my file I have: <div style="font-weight: bold;font-size: x-large">Some <span style="color: orange">HTML</span></div>)
Set Build Action to Embedded Resource for the html
Add [assembly: System.Web.UI.WebResource("MyFramework.content.html.myhtml.html", "text/html")] to AssemblyInfo.cs
Add protected string MyHtmlUrl { get; private set; } so we can access the HTML in the inheriting class
Add:
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "MyFramework.content.html.myhtml.html";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream))
{
MyHtmlUrl = reader.ReadToEnd();
}
}
In the consuming project MyModule:
Add <%=MyHtmlUrl%> to View.ascx
I'm creating a WPF application which loads its plugin using MEF.
How can I include resources from another assembly I'm loading using MEF?
Specifically I want to create an HierarchicalDataTemplate in external assembly and load it to a Treeview.Resources dynamically when composing the application on start.
Is something like this possible?
I'm using Caliburn.Micro if it matters but I'm sure the question applies to general WPF applications.
If you try to load static resources you should load the resource before loading the main window.
If you try to load dynamic resources you should load the resource before loading the view that uses the resource.
Any way you should add a reference to the resource by adding it to the Wpf Application merge dictionary while bootstrapping.
//On the bootstrapper add the following code
ResourceDictionary rd = new ResourceDictionary
{
Source =
new Uri(
"pack://application:,,,/DllName;component/Themes/ResourceName.xaml",
UriKind.RelativeOrAbsolute)
};
Application.Current.Resources.MergedDictionaries.Add(rd);
This is how I did it at the end.
Because Caliburn.Micro doesn't work properly if you use MEF's DirectoryCatalog to load your assemblies I had to do it manually. Bellow is the simplified part of the code that does it and loads the ResourceDictionary contained in the separate resources.xaml file.
FileInfo[] filesInfo = new DirectoryInfo(pluginPath).GetFiles("*.dll");
AssemblySource.Instance.AddRange(filesInfo.Select(fileInfo => Assembly.LoadFrom(fileInfo.FullName)));
// load resources from plugins
var dictionaries = App.Current.Resources.MergedDictionaries;
dictionaries.Clear();
foreach (FileInfo fileInfo in filesInfo)
{
string assemblyName = Path.GetFileNameWithoutExtension(fileInfo.Name);
string uriString = assemblyName + #";component/resources.xaml";
try
{
dictionaries.Add(new ResourceDictionary { Source = new Uri(uriString, UriKind.Relative) });
}
catch
{
// do some logging
}
Good Day,
I have just started learning visual F#, and it looks surprisingly fun to do. For my first project I got my hands dirty by immediately make a windows form to download info from a page and display it in a RichTextBox on the form. Problem is, once the form shows and information is downloaded, it immediately closes. How do I keep my masterpiece open for viewing? Any advice?
I have 2 Files currently:
Program.fs
Script1.fs
Program.fs is supposed to "create" the form, where Script1.fs is merely the entrypoint for the application.
Program.fs
namespace Program1
open System.Windows.Forms
module public HelloWorld =
let form = new Form(Visible = true, TopMost = true, Text = "Welcome to F#")
let textB = new RichTextBox(Dock = DockStyle.Fill, Text = "Initial Text")
form.Controls.Add textB
open System.IO
open System.Net
/// Get the contents of the URL via a web request
let http (url: string) =
let req = System.Net.WebRequest.Create(url)
let resp = req.GetResponse()
let stream = resp.GetResponseStream()
let reader = new StreamReader(stream)
let html = reader.ReadToEnd()
resp.Close()
html
textB.Text <- http "http://www.google.com"
Script1.fs
open Program1
[<EntryPoint>]
let main argv=
printfn "Running F# App"
HelloWorld.form.Show();
0
I need to reiterate, I started with F#. This is my first application I wrote. How do I keep the form open?
You need to call Application.Run and pass your form object into it. http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run(v=vs.110).aspx
This will create a message loop, and keep your application alive until the form is closed.
open Program1
[<EntryPoint>]
let main argv=
printfn "Running F# App"
System.Windows.Forms.Application.Run(HelloWorld.form)
0
I have a WPF control hosted in Windows Forms and I would like to access it's resources, specifically images. What is the best way to do that?
I was thinking of using a ResourceDictionary, but I'm not sure how I can access it from within a Windows Form.
This is a standalone WPF control, in a DLL? There are two ways that the resources can be embedded... as part of a .resources file (e.g. the Project's "Resoruces" tab), or as files included as "Embedded Resources"...
To get the assembly reference to the DLL this is usually the easiest:
var ass = typeof(ClassInOtherDll).Assembly;
In the Resources
If this is part of the default project resources, and not a different .resources file included inside the DLL, you can use the default base-name.
var ass = typeof(ClassInTargetDLL).Assembly;
var rm = new ResourceManager("...BaseName...", ass);
BaseName for default project resources is :
C# := Namespace.Properties.Resources
VB := Namespace.Resources
After that you can just call GetObject() and do a cast back:
var myImage = rm.GetObject("check_16");
return myImage as Bitmap;
If you want to find out whats in there, get the assembly reference and call
ass.GetManifestResourceNames()
.resources files can be used with a ResourceManager
embedded resources will just show up as a list. Use the other method for these.
And this is all assuming they default culture =)
As Embedded Resources
You can use the regular methods on the assembly to get an embedded resource. You find it by name, and then Basically you will need to convert the stream back into your desired type.
GetManifestResourceNames()
GetManifestResourceStream(name)
help getting the desired file with a helper function to find files by name.
I usually use these like this:
// called GetMp3 in the post, but it returns a stream. is the same thing
var stream = GetResourceStream("navigation.xml");
var reader = New XmlTextReader(stream);
return reader;
To get an image that is an embedded resource, this works for me:
var stream = GetResoureStram("check_32.png");
var bmp = new Bitmap(stream);
this.MyButton.Image = bmp;