Run method missing in xaml class - wpf

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.

Related

IOException when referencing App.xaml's ResourceDictionary

I'm trying to reference App.xaml's ResourceDictionary from a separate WPF window. I want to use resources from there in different windows, and this seems like the recommended way to do it. Unfortunately, I don't seem to be able to effectively reference App.xaml from the other window. Here is my App.xaml:
<Application x:Class="View.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ViewModel="clr-namespace:ViewModel;assembly=ViewModel"
xmlns:local="clr-namespace:View"
StartupUri="ClockView.xaml">
<Application.Resources>
<ResourceDictionary>
<local:PriorityToIconConverter x:Key="PriorityToIconConverter" />
</ResourceDictionary>
</Application.Resources>
Notes: I'm not using MainWindow, so I've replaced the startup URI with a form that always comes up. I noted that in some other answers, the location of MainWindow is sometimes the issue. In my case, I haven't seen any difference between using ClockView or MainWindow. Both ClockView and MainWindow exist in the root namespace, MainWindow is just never loaded. I also have more resources, but I've removed them for the sake of conciseness.
Here's a simplified example of the code where I'm trying to reference the ResrouceDictionary from App.xaml:
<local:AssistantWindow
x:Class="View.AutomatorView"
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:properties="clr-namespace:View.Properties"
xmlns:local="clr-namespace:View"
mc:Ignorable="d"
Title="Tool"
x:Name="Tool"
Background="Transparent"
Height="600"
Width="450"
Topmost="{Binding Source={x:Static properties:Settings.Default}, Path=ToolAlwaysOnTop}"
MinHeight="515"
MinWidth="150">
<Window.Resources>
<ResourceDictionary Source="App.xaml" />
</Window.Resources>
Again, this is simplified to be concise. When I try to load this form, I get the exception:
System.Windows.Markup.XamlParseException: ''Set property 'System.Windows.ResourceDictionary.Source' threw an exception.' Line number '21' and line position '10'.'
Inner Exception
IOException: Cannot locate resource 'tool/app.xaml'.
The view for "Tool" is located in a folder that is also named "Tool." However, the xaml and code behind don't reference this namespace, I'm just using the folder to organize my classes. It looks like it's looking for App.xaml in the folder the view resides in. App.xaml resides in the root namespace (View). I've tried modifying the source in the xaml for Tool to:
- View.App.xaml
- View:App.xaml
- View/App.xaml
How can I get this reference to work, so I can share resources throughout my application? Thank you.
You can't load App.xaml like you're trying to do because it's not actually a ResourceDictionary. You can only specify ResourceDictionary files as the target of Source.
However, if you declare a resource in App.xaml, you can reference it anywhere without needing to load the file it's in. That's done for you automatically. Therefore, you can reference your converter at any time with {StaticResource PriorityToIconConverter}.
Note that if you moved it from the default starting location (the base project folder) you may have to update its location. Right click your project, then Properties. Navigate to the "Application" tab (should be the uppermost element on the left-hand sidebar) and look for the "Startup object" field. Set that to [ProjectName].[Namespace?].[Namespace?].App. When I tested it, mine worked without needing to manually change the location, but your setup may be different.

Should these names coincide in WPF application project?

I would like to know if this names (StartupUri="MainWindow.xaml" and MainWindow.xaml) should coincide. For example, if I'm going to rename MainWindow.xaml to e.g. MsgBox.xaml.
Please look at pic and code sample.
Solution explorer tree view
App.xaml of project CustomMessageBox
<Application x:Class="CustomMessageBox.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomMessageBox"
StartupUri="MainWindow.xaml"> <!-- this name -->
<Application.Resources>
</Application.Resources>
Please any comments and thanks in advance.
That is the name of the window that will be opened when the app starts. If you rename the window without changing the StartupURI you will get a System.IO.IOException, Cannot locate resource 'mainwindow.xaml'.

Call method on Window Loaded Event in F# with WPF

I am getting a XAMLParseException when trying to load a xaml component with a Loaded event. I am not quite sure how write the method signature for the handled event. C# examples are clear but I'm not sure how to convert this to the F# version. I will include my first attempt below.
ViewModel code:
let theWindow = Application.LoadComponent(new Uri("/MyApp;component/MyWindow.xaml", UriKind.Relative)) :?> Window
XAML Header:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:MyApp.Converters;assembly=MyApp"
xmlns:local="clr-namespace:MyApp;assembly=MyApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
x:Name="_theWindow"
WindowStartupLocation="CenterOwner"
Title="My App - Popup Window"
Loaded="Window_Loaded"
Icon="MyApp;component/icons/MyApp.ico"
Width="484.667" Height="215.333"
Left="100" Top="100">
F# method:
member x.Window_Loaded (sender : object, eventArgs : RoutedEventArgs) = // Do stuff
When using FsXaml.Wpf v.3.1.3 I had...
StartupUri="MainWindow.xaml"
...in my app.xaml file. I removed it and used this in my App.fs file to open MainWindow.xaml...
[<STAThread>]
[<EntryPoint>]
let main argv =
Wpf.installSynchronizationContext ()
Views.MainWindow()
|> App().Run
...which matches the WpfMvvmAgent demo. That resolved the XamlParseException above for me.

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

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.

Error when adding code behind for Silverlight resource dictionary: AG_E_PARSER_BAD_TYPE

It should be possible to add a code behind file for a resource dictionary in Silverlight, but I keep getting the same error, thrown from the InitializeComponent method of my App.xaml constructor: XamlParseException: AG_E_PARSER_BAD_TYPE.
The resource dictionary xaml file looks like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Celerior.Annapurna.SL.ProvisiorResourceDictionary"
x:ClassModifier="public">
...
</ResourceDictionary>
If I remove the x:Class attribute everything works fine again (of course, I double-checked the class name and it's correct). My App.xaml file isn't really exciting and just contains a reference to the resource dictionary:
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Celerior.Annapurna.SL.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ProvisiorResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
What am I doing wrong?
Kind regards,
Ronald Wildenberg
Silverlight does not support the x:ClassModifier thats only supported in WPF.
In addition x:Class isn't valid in a Resource dictionary. Certainly when trying to include the Xaml from the resource dictionary as a merged dictionary Silverlight wouldn't know what to do with the x:Class at that point.
Actually the above isn't strictly true x:Class is valid but the way you are including the dictionary in the application dictionary needs tweaking. Let me first just state that there is the assumption here that you actually need to sub-class ResourceDictionary (if not just drop the x:Class).
I'm also going to go out on a limb based on your inclusion of x:ClassModifier that you actually don't have a ProvisiorResourceDictionary.xaml.cs file in your project. Since SL always creates a public partial you need this file to contain at least:-
public partial class ProvisiorResourceDictionary
{
public ProvisiorResourceDictionary()
{
InitializeComponent();
}
}
That said if don't have something like this already then you may as well just drop x:Class altogether.
Now your app.xaml needs to look like this:-
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<common:ProvisiorResourceDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Instead of trying to import the XAML file as resource via the Source property you now include an instance of the specialised ResourceDictionary.
Is the ProvisiorResourceDictionary class public? If not, maybe you need to specify the x:ClassModifier attribute as well.

Resources