2011-04-27 19 views
14

Tengo una ventana emergente con StaysOpen=False así que quiero cerrarla haciendo clic en cualquier lugar fuera de la ventana emergente. Dentro de una ventana emergente tengo un DataGrid. Si abro la ventana emergente y luego hago clic en otro lugar, la ventana emergente se cerrará. Pero no sucederá si antes de hacer clic fuera de la ventana emergente voy a hacer clic en el encabezado de la columna en DataGrid. XAML prueba:wpf popup no se cierra automáticamente cuando datagrid dentro del menú emergente captura el mouse

<Window x:Class="Test.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" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black"> 
<Grid> 
    <ToggleButton x:Name="btn" VerticalAlignment="Top">Open</ToggleButton> 
    <Popup StaysOpen="False" IsOpen="{Binding IsChecked, ElementName=btn}" > 
     <DataGrid Width="150" Height="150"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="Column" /> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Popup> 
</Grid> 
</Window> 

creo que se debe a título de columna captura el ratón en clic y emergente no recibe eventos de ratón más. Intenté agregar un controlador en el evento LostMouseCapture para capturar el mouse de nuevo mediante una ventana emergente, pero parece que no funciona tan fácil. ¿Algunas ideas?

Respuesta

2

Creo que te has tropezado con un simple error. He reproducido esto y no he podido encontrar una forma razonable de hacerlo funcionar. Creo que deberías presentar un error con Microsoft. Parece que un componente que captura el mouse y los incaptures no restaura la captura al componente de captura original.

2

Tuve un problema similar recientemente, aunque no exactamente lo mismo, y fue en Silverlight. Me abrí paso a través de ello buscando el control requerido (en su caso, la ventana emergente, supongo) con la función GetTemplatedParent, en el controlador de eventos requerido del control de "comportamiento indebido", y programáticamente hago lo que quería hacer en él.

Esta no es una buena solución, y no resuelve todos los problemas, pero puede intentarlo. Asegúrate de comentar lo que has hecho, porque puede convertirse en un desastre.

0

tuve el mismo problema, e hizo algo como esto:

private void YourDataGrid_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     YourDataGrid.CaptureMouse(); 
     YourDataGrid.ReleaseMouseCapture(); 
    } 

pero yo estoy buscando algo mejor aún ...

4

Tal vez pueda ayudar. comportamiento adjunto:

public class DataGridColumnHeaderReleaseMouseCaptureBehavior { 
    public static DataGrid GetReleaseDGCHeaderBehavior(DependencyObject obj) { 
     return (DataGrid)obj.GetValue(ReleaseDGCHeaderBehaviorProperty); 
    } 

    public static void SetReleaseDGCHeaderBehavior(DependencyObject obj, Boolean value) { 
     obj.SetValue(ReleaseDGCHeaderBehaviorProperty, value); 
    } 

    public static readonly DependencyProperty ReleaseDGCHeaderBehaviorProperty = 
     DependencyProperty.RegisterAttached("ReleaseDGCHeaderBehavior", 
      typeof(DataGrid), 
      typeof(DataGridColumnHeaderReleaseMouseCaptureBehavior), 
      new UIPropertyMetadata(default(DataGrid), OnReleaseDGCHeaderBehaviorPropertyChanged)); 

    private static Popup _popup; 

    private static void OnReleaseDGCHeaderBehaviorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
     var oldGrid = (DataGrid)e.OldValue; 
     if (oldGrid != null) 
      oldGrid.MouseLeave -= OnMouseLeave; 
     var refSender = d as Popup; 
     _popup = refSender; 
     if (refSender != null) { 
      var refGrid = e.NewValue as DataGrid; 
      if (refGrid != null) { 
       refGrid.MouseLeave += OnMouseLeave; 
      } 
     } 
    } 
    static void OnMouseLeave(object sender, MouseEventArgs args) { 
     if (_popup != null) 
      typeof(Popup).GetMethod("EstablishPopupCapture", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(_popup, null); 
    } 
} 

XAML:

<Popup x:Name="popup" 
bhvrs:DataGridColumnHeaderReleaseMouseCaptureBehavior.ReleaseDGCHeaderBehavior="{Binding ElementName=dataGrid}"> 
    <DataGrid x:Name="dataGrid"/> 
</Popup> 
+0

Esto funciona ... debe ser marcado como respuesta :) – user589195

Cuestiones relacionadas