Why can't I launch a WPF app written in F#? - wpf

I receive the following warning when attempting to build a WPF app written in F#:
Main module of program is empty: nothing will happen when it is run
As a result, I am unable to launch the application.
I have verified that all AssemblyInfo.fs files has a "do()" at the end.
I have played around with the order of files as well.
Any suggestions?
UPDATE
I Added a file to the end of my project.
The file has the following code:
module Bootstrap
open System.Windows
[<EntryPoint>]
let main args =
System.Windows.Application.Current.Run() |> ignore;
// Return 0. This indicates success.
0
When I attempt to run the file though, I hit a null reference exception on Application.Current.
My solution looks like this:

Here's a minimal working example, using FSharp.ViewModule.Core and FsXaml.Wpf packages:
MainWindow.xaml:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:ViewModel;assembly=fsxamltest">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
</Window>
ViewModel.fs:
namespace ViewModel
open FSharp.ViewModule
type MainViewModel() as me = inherit ViewModelBase()
App.fs:
open System
type App = FsXaml.XAML<"App.xaml">
[<STAThread;EntryPoint>]
let main _ = App().Root.Run()
App.xaml:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"/>
If that doesn't work, please show us the full code or create MCVE.

Related

Command line equivalent of Visual Studio Add New Page (WPF)

In the WPF first desktop app walkthrough, it uses Visual Studio to explain how to create a new page in a WPF project. I don't use Visual Studio, but I want to make an XAML Page file using the terminal. I can't just create a new file because it has prewritten code for a new Page similar to below:
<Page x:Class="ExpenseIt.ExpenseItHome"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="350" d:DesignWidth="500"
Title="ExpenseIt - Home">
<Grid>
</Grid>
</Page>
I checked the dotnet new documentation and it says nothing about creating a new file. I know I can just have the default contents in a separate file which I can copy and paste but this seems like an inelegant workaround. Is there a command line argument or another way to get the Page WPF Template without Visual Studio?
Edit
To be more specific on what I am looking for, I would like an XAML file and its corresponding .xaml.cs code-behind file with all the using statements. As suggested, I can use XamlReader, which I have tried, but I would preferably like a tool. XamlPadX is outdated and does not have the code-behind that I am looking for.
Edit 2
This is my current code in the console app I am making:
if (args[0].StartsWith("loadpage-"))
{
string className = args[0].Substring("loadpage-".Length);
string xamlOutput = String.Join(
Environment.NewLine,
$"<Page x:Class=\"{className}\"",
"xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"",
"xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"",
"xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"",
"xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"",
"mc:Ignorable=\"d\"",
"d:DesignHeight=\"350\" d:DesignWidth=\"500\"",
$"Title=\"\">",
"<Grid>", "", "</Grid>",
"</Page>");
Console.WriteLine(xamlOutput);
}
else
{
Console.WriteLine("You must enter the argument in the following format: ");
Console.Write("loadpage-CLASSNAME");
}
You could write a console application which uses command line arguments to receive the xaml content via pure text, or text file containing the content of the xaml page.
Load it using XamlReader in Main method of your program.cs:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.markup.xamlreader?view=netcore-3.1

How to assemble a Namespace in a WPF project

I'm learning WPF and trying to reproduce this DataTemplate example related to this article, writing the code-behind in VB (in the example is in C#). The first issue I'm facing is that I don't know how to assemble a Namespace created in the MainWindow.xaml.vb file. I read a lot of questions related here but I haven't been able to find a solution. I recompile the project and it run properly but the error is still there. I also read that could be a VS bug related with the architecture setting of the app (x64 x86).
MainWindow.xaml file:
<Window x:Class="DataTemplatingIntro.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SDKSample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
MainWindow.xaml.vb file:
Imports System.Windows
Namespace DataTemplatingIntro
Public Class MainWindow
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
Severity Code Description Project File Line Status deleted
Error XLS0414 The type 'DataTemplatingIntro.MainWindow' was not found. Verify that a reference to an assembly is not missing and that all referenced assemblies have been compiled. SDKSample MainWindow.xaml
I tried to add the name of the assembly:
xmlns:myns="clr-namespace:DataTemplatingIntro;assembly=MyLibAssembly
I tried to add as local too:
xmlns:local="clr-namespace:SDKSample:DataTemplatingIntro"
But nothing works. How can I solve this annoying VS issue?
Thanks in advance

Run method missing in xaml class

I am using F# and XAML in order to create a GUI but unfortunately after creating the type for the xaml I don't have a run method available. What am I missing here?
code :
module Program
open FsXaml
open System
type App = XAML<"App.xaml">
[<STAThread>]
[<EntryPoint>]
let main argv =
let app = App()
app.Run()
App.xaml should contain an Application, not a window:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
this will provide a Run method. Make sure you add a xaml file "MainWindow.xaml" with a window defined in it.

How can I use WPF menus and dialog boxes in F#?

I've been trying to find an example of using XAML and F# - without C# - to set up traditional menus and dialog boxes. Everything I can find online either uses C# or it is old, before the most recent versions of F# and .NET. Can anyone suggest an example I can look at? Thanks.
When you try to learn WPF, you come across many C# examples based on "good old" code behind rather than MVVM or MVC. The following explains how to quickly create an F# WPF code behind application. Using this, it becomes easier to experiment with all those examples.
Create an F# console application.
Change the Output type of the application to Windows Application.
Add FsXaml from NuGet.
Add these four source files, and arrange them in this order.
MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="First Demo" Height="200" Width="300">
<Canvas>
<Button Name="btnTest" Content="Test" Canvas.Left="10" Canvas.Top="10" Height="28" Width="72"/>
</Canvas>
</Window>
MainWindow.xaml.fs
namespace FirstDemo
type MainWindowXaml = FsXaml.XAML<"MainWindow.xaml">
type MainWindow() =
inherit MainWindowXaml()
let whenLoaded _ =
()
let whenClosing _ =
()
let whenClosed _ =
()
let btnTestClick _ =
this.Title <- "Yup, it works!"
()
do
this.Loaded.Add whenLoaded
this.Closing.Add whenClosing
this.Closed.Add whenClosed
this.btnTest.Click.Add btnTestClick
App.xaml
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>
App.xaml.fs
namespace FirstDemo
open System
open System.Windows
type App = FsXaml.XAML<"App.xaml">
module Main =
[<STAThread; EntryPoint>]
let main _ =
let app = App()
let mainWindow = new MainWindow()
app.Run(mainWindow) // Returns application's exit code.
Delete the Program.fs file.
Change the Build Action to Resource for the two xaml files.
Add a reference to the .NET assembly UIAutomationTypes.
Compile and run.
You can't use the designer to add event handlers. Simply add them manually in the code behind.
StackOverflow is possibly not the best place to post complete demos like this one, especially if this spins off more questions along the same line. If there is another better place, e.g. a public repo for this kind of thing, please let me know.

windowsformhost cant load a usercontrol from another dll

So I have a dll from another project which contains many useful classes and controls for me (lets call it foo.dll). I'm making an WPF app. I need to use some of them in my app. I created my usercontrol for windows forms and referenced UserControlForMe from foo.dll. It's shown, all good. Now I want to insert my usercontrol into a wpf form. It looks like this:
<UserControl x:Class="FlatRectangular_Profile.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:uc="clr-namespace:FlatRectangular_Profile.UC"
Height="2093" Width="717">
<Grid Name="grid">
<WindowsFormsHost>
<uc:WindowsFormsProfManual ></uc:WindowsFormsProfManual>
</WindowsFormsHost>
</Grid>
</UserControl>
But here I get an error "cant load type UserControlForMe from foo.dll". No info on that error. Again, UserControlForMe loads in WindowsFormsProfManual. All these is going on in one class library. I referenced everything that foo.dll needed.
No idea how what to do next. I also tried to load it in code in usercontrol.loaded event, but it fails too, and shows stacktrace which leads to the constructor of the UserControlForMe.
I guess you'll have to add the assembly to your namespace import to point your application in the right direction:
xmlns:uc="clr-namespace:FlatRectangular_Profile.UC;Assembly=MyDLL"
I found a workaround since I cant get why it is not working. If I load a UserControlForMe from foo.dll directly to the windowsformhost, it works. But if there is a "buffer" dll, it works in this dll, but doesnt open in futher window. Also I add a UserControlForMe programmatically to a windowsformhost.

Resources