Home > other >  Minimising a WPF window in FsXaml
Minimising a WPF window in FsXaml

Time:12-04

I am trying to convert this C# (WPF MVVM) code for minimising a WPF window into F#/FsXaml.

using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = DependencyInjector.Retrieve<MainWindowViewModel>();
        }
        
        //... some generated code

        private void OnKeyDownHandler(object sender, System.Windows.Input.KeyEventArgs e)
            => this.WindowState = (e.Key == Key.Escape) ? (WindowState)FormWindowState.Minimized : (WindowState)FormWindowState.Normal;
    }

How to convert the C# code with OnKeyDownHandler into F#/FsXaml (only code behind, no MVVM)?

I did try to create the equivalent code in F#/FsXaml, but without success - see below.

open System.Windows.Input
type MainWindowXaml = FsXaml.XAML<"XAMLAndCodeBehind/MainWindow.xaml">

type MainWindow() as this =
    inherit MainWindowXaml() 
    
    //... some code  
   
    let MyOnKeyDownHandler (e: System.Windows.Input.KeyEventArgs) = 
        match (e.Key = Key.Escape) with 
        | true  -> this.WindowState <- Windows.WindowState.Minimized
        | false -> this.WindowState <- Windows.WindowState.Normal
    
    do        
        this.KeyDown.Add MyOnKeyDownHandler 

The line with type MainWindow() gives these two errors:

No implementation was given for 'MainWindowXaml.OnKeyDownHandler(sender: obj, e: KeyEventArgs) : unit'

This type is 'abstract' since some abstract members have not been given an implementation. If this is intentional then add the '[]' attribute to your type.

Both relevant xaml files (in C# as well as in my F# attempt) contain KeyDown="OnKeyDownHandler" in the DataContext section.

EDIT: Added the relevant part of the XAML file:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Icon= ......
    KeyDown="OnKeyDownHandler"
    WindowStartupLocation="CenterScreen"
    Title="...">
    <Canvas Margin="0,0,2,2">
      //... some XAML code...
    </Canvas>
</Window>

CodePudding user response:

I do not have direct experience with FsXaml, but the pattern you are using seems to be similar to the one in the WpfSimpleMvvmApplication sample. Here, the xaml file defines an event handler OnFullNameDoubleClick. This then becomes an abstract method in the generated class that needs to be overriden in the corresponding F# source file.

This means that your OnKeyDownHandler (which is presumably defined in the XAML file that is not included with your question) needs to be defined as an overriden method (and FsXaml automatically attaches the event handler):

open System.Windows.Input
type MainWindowXaml = FsXaml.XAML<"XAMLAndCodeBehind/MainWindow.xaml">

type MainWindow() =
    inherit MainWindowXaml() 
    
    //... some code  
   
    override this.OnKeyDownHandler(_:obj, e: System.Windows.Input.KeyEventArgs) = 
        match (e.Key = Key.Escape) with 
        | true  -> this.WindowState <- Windows.WindowState.Minimized
        | false -> this.WindowState <- Windows.WindowState.Normal

EDIT: I also deleted as this from the class definition, because this was no longer needed - you can access this via the method definition (and this is a bit simpler).

  • Related