Passing window handle to view model in WPF with MV

2019-07-14 01:58发布

问题:

I am using an external library which requires a window handle. My application architecture is MVVM, but the external library doesn't exactly fit into this architecture. I have decided that the view model is the most appropriate place to call an initialization function which requires a window handle. How can I get the window handle from my view to my view model?

回答1:

Typically, your view model shouldn't know about the implementation details of your view (such as it's HWND). However, as your question indicates, the external library you are using requires you to initialize it, and you can only do that in one place. Assuming that your view model is the most appropriate place for it (it might even belong in the model), you can do something like the following.

This implementation provides the window handle to your view model as soon as all the pieces are available. Note that the view model implementation that you provided in your previous question requires the HWND in the view model's constructor. You're going to have to change your view model so that the initialization happens via an explicitly called method or property. In the code below, I assume that there is a method in your view model called OnWindowHandleAvailable. You could certainly call that method Initialize instead, or you could put a Handle property on your view model which you explicitly set.

public partial class View
{
    public View()
    {
        InitializeComponent();
        this.Loaded += View_Loaded;
        this.DataContextChanged += View_DataContextChanged;
    }

    private void View_Loaded(object sender, RoutedEventArgs e)
    {
        GiveWindowHandleToViewModel();
    }

    private void View_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        GiveWindowHandleToViewModel();
    }

    private void GiveWindowHandleToViewModel()
    {
        // get view model
        var viewModel = this.DataContext as ViewModel;
        if (viewModel == null)
            return;

        // get window handle
        var windowHandle = this.GetWindowHandle();
        if (windowHandle == IntPtr.Zero)
            return;

        // signal view model
        viewModel.OnWindowHandleAvailable(windowHandle);
    }

    private IntPtr GetWindowHandle()
    {
        // get window
        var window = Window.GetWindow(this);
        if (window == null)
            return IntPtr.Zero;

        // get window handle
        return new WindowInteropHelper(window).Handle;
    }
}


标签: c# wpf mvvm