开发者

Understanding why WPF KeyBinding works in test but not in winforms application

开发者 https://www.devze.com 2023-02-18 18:04 出处:网络
I have a topmost dialog box that hides itself when someone presses a button or hits escape. (Code shown is a much simplified version to highlight the issue encountered.)

I have a topmost dialog box that hides itself when someone presses a button or hits escape.

(Code shown is a much simplified version to highlight the issue encountered.)

If I launch the dialog as follows everything works fine.

var dialog = new MyDialog(new MyDialogViewModel());
n开发者_如何学JAVAew Application().Run(dialog);

If I open the dialog as follows then the escape key binding won't work but the button still does.

new MyDialog(new MyDialogViewModel()).Show();

MyDialog.xaml

<Window x:Class="MyDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   
    Topmost="True"
    Visibility="{Binding Visibility}">

    <Window.InputBindings>
        <KeyBinding Key="Escape" Command="{Binding HideCommand}" />
    </Window.InputBindings>

    <Button Command="{Binding HideCommand}">Hide</Button>
</Window>

MyDialog.xaml.cs

public partial class MyDialog : Window
{
    public MyDialog(MyDialogViewModel vm)
    {
        DataContext = vm;
        InitializeComponent();
    }
}

MyDialogViewModel.cs

public class MyDialogViewModel : INotifyPropertyChanged
{
    private Visibility _visibility = Visibility.Visible;

    public MyDialogViewModel()
    {
        HideCommand = new DelegateCommand(Hide);
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    public DelegateCommand HideCommand { get; private set; }

    public Visibility Visibility 
    { 
        get
        {
            return _visibility;
        }
        set 
        { 
            _visibility = value;
            PropertyChanged();
        }
    }

    private void Hide()
    {
        Visibility = Visibility.Hidden;
    }
}

Using Snoop I can see the following binding error, this is present when launched either way.

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=HideCommand; DataItem=null; target element is 'KeyBinding' (HashCode=30871361); target property is 'Command' (type 'ICommand')

I'm trying to understand why the escape key works in one scenario and not the other. Any ideas?


A few thoughts/questions:

  1. In the version that does not work, where are you opening the dialog? From the main window that is started by the application?

  2. In your MyDialog constructor, I'm assuming you have a call to InitializeComponent. Is that correct? Otherwise, it would not properly initialize from the XAML file.

  3. Is there a reason you cannot use the Button.IsCancel property?

EDIT:

If you are loading a WPF Window from a WinForms application you need to do some additional work. This blog explains this and includes the following example:

using System;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
....
var wpfwindow = new WPFWindow.Window1();
ElementHost.EnableModelessKeyboardInterop(wpfwindow);
wpfwindow.Show();


I wonder if it's a timing issue with the KeyBinding. I just checked one of my projects that has tons of KeyBinding and the commands are all static so there would be no issue. I wonder if perhaps the KeyBinding command binding is occurring before the VM is updated and the binding is never being updated.

UPDATE: Check this out, it may be the answer: http://joyfulwpf.blogspot.com/2009/05/mvvm-commandreference-and-keybinding.html

and this: Keybinding a RelayCommand

0

精彩评论

暂无评论...
验证码 换一张
取 消