WPF: How to pass WindowHandle to ViewModel using MVVM pattern

Create a Behavior with dependency property as shown below:

using System;

using System.Diagnostics.CodeAnalysis;

using System.Windows;

using System.Windows.Interactivity;

using System.Windows.Interop;


namespace My.Windows.Controls.Behaviors

{

    [ExcludeFromCodeCoverage]

public class WindowHandleMVVMBehavior : Behavior<Window>

{

public IntPtr WindowHandle

{

get { return (IntPtr)GetValue(WindowHandleProperty); }

set { SetValue(WindowHandleProperty, value); }

}


public static readonly DependencyProperty WindowHandleProperty =

DependencyProperty.Register("WindowHandle", typeof(IntPtr), typeof(WindowHandleMVVMBehavior), 

new FrameworkPropertyMetadata(IntPtr.Zero, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));


protected override void OnAttached()

{

base.OnAttached();

if (AssociatedObject != null)

{

AssociatedObject.Loaded += OnWindowLoaded;

}

}


private void OnWindowLoaded(object sender, RoutedEventArgs e)

{

var window = sender as Window;

var windowHandle = GetWindowHandle(window);

WindowHandle = windowHandle;

}


protected override void OnDetaching()

{

base.OnDetaching();

if (AssociatedObject != null)

{

AssociatedObject.Loaded -= OnWindowLoaded;

}

}


private IntPtr GetWindowHandle(Window window)

{

return window is null ? IntPtr.Zero : new WindowInteropHelper(window).Handle;

}

}

}

Use the Behavior in XAML like this:

<Window x:Class="Applications.Views.MainView"
        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">
    <i:Interaction.Behaviors>
<behaviors:WindowHandleMVVMBehavior WindowHandle="{Binding WindowHandle, Mode=TwoWay}"/>
    </i:Interaction.Behaviors>
</Window>

Create Property in your ViewModel (DataContext of MainView) similar to this one:
private IntPtr _windowHandle;
        public IntPtr WindowHandle
        {
        get { return _windowHandle; }
        set
        {
        _windowHandle = value;
        }
        }

Comments

Popular posts from this blog

WPF How to Dispose ViewModel when the associated UserControl (Not Window) closes?

C# How to unit test Dispatcher

WPF: How to Deep Copy WPF object (e.g. UIElement) ?