El comando enrutado WPF que habilita funciona con el menú pero no con un botón

En el siguiente ejemplo, el menú está habilitado cuando el texto recibe el foco pero no el botón. Lo he probado con solo el botón y el cuadro de texto pero el comportamiento es el mismo.

<Window x:Class="WpfPopup.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<DockPanel>
    <Menu DockPanel.Dock="Top">
        <MenuItem  Command="ApplicationCommands.Paste" />
    </Menu>
    <TextBox BorderBrush="Black" BorderThickness="2" Margin="25" TextWrapping="Wrap" x:Name="text1" Height="58" Width="203" >
        The MenuItem will not be enabled until
        this TextBox gets keyboard focus
    </TextBox>        
    <Button Content="Button" Height="23" Name="button1" Width="93" Command="ApplicationCommands.Paste" />
</DockPanel>

preguntado el 21 de mayo de 12 a las 11:05

1 Respuestas

Hay dos formas simples de arreglar esto:

1) Utilice FocusManager.IsFocusScope:

    <Button Content="Button" Height="23" Name="button1" Width="93" Command="ApplicationCommands.Paste" FocusManager.IsFocusScope="True"/>

2) Establezca CommandTarget en el botón manualmente:

<Button Content="Button" Height="23" Name="button1" Width="93" Command="ApplicationCommands.Paste" CommandTarget="{Binding ElementName=text1}" />

Probablemente se esté preguntando por qué esto funciona para el elemento del menú. Si lee la documentación de FocusManager.IsFocusScope propiedad adjunta obtendrá la respuesta:

De forma predeterminada, la clase Window es un ámbito de enfoque, al igual que las clases Menu, ContextMenu y ToolBar. Un elemento que es un ámbito de enfoque tiene IsFocusScope establecido en verdadero.

¡Muy confuso cuando no sabes eso!

contestado el 21 de mayo de 12 a las 11:05

Muchas gracias, muy esclarecedor. Estoy empezando a ver por qué el botón se trata de manera diferente. Una cosa que noté es que sin FocusManager.IsFocusScope="True", el botón quita el foco del cuadro de texto mientras que el menú no lo hace. Cuando se aplica la propiedad, el botón se comporta como el menú. Supongo que esto tiene sentido cuando lo piensas: el comando debe habilitarse cuando un control que puede aceptarlo tiene el foco. Sin embargo, cuanto más uso WPF, más parece magia negra. - Shane

Por lo general, colocaría la propiedad en un panel, por ejemplo, un StackPanel que contiene el botón. Si ayuda, hay mucho sobre esto en el libro Pro WPF en C# 2010 en el capítulo de comandos (capítulo 9). - RichardOD

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.