16

ポップアップがStaysOpen=Falseあるので、ポップアップの外側をクリックして閉じたいと思います。ポップアップの中にはがありDataGridます。ポップアップを開いてから別の場所をクリックすると、ポップアップが閉じます。ただし、ポップアップの外側をクリックする前に、の列ヘッダーをクリックすると、発生しませんDataGrid。XAMLのテスト:

<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>

これは、列ヘッダーがクリック時にマウスをキャプチャし、ポップアップがマウスイベントを受信しなくなったために発生したと思います。ポップアップでマウスをキャプチャするために、イベントにハンドラーを追加しようとしましたLostMouseCaptureが、それほど簡単には機能しないようです。何か案は?

4

4 に答える 4

5

多分それは役立つでしょう。付随する振る舞い:

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>
于 2012-11-27T06:56:56.020 に答える
2

あなたはただの古いバグに出くわしたと思います。私はこれを再現しましたが、それを機能させるための合理的な方法を見つけることができませんでした。マイクロソフトにバグを報告する必要があると思います。マウスをキャプチャするコンポーネントのように見えますが、キャプチャを解除しても、キャプチャは元のキャプチャコンポーネントに復元されません。

于 2011-04-29T18:55:36.327 に答える
2

私は最近、まったく同じではありませんが、同様の問題を抱えていました。それはSilverlightにありました。GetTemplatedParent関数を使用して、「誤動作」コントロールの必須イベントハンドラーで必要なコントロール(この場合はポップアップ)を検索し、プログラムで実行したいことを実行することで、ハッキングしました。

これは良い解決策ではなく、すべての問題を解決するわけではありませんが、試してみることができます。それは混乱に変わる可能性があるので、あなたがしたことをコメントすることを忘れないでください。

于 2011-09-03T09:19:51.207 に答える
0

私は同じ問題を抱えていて、次のようなことをしました:

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

しかし、私はまだもっと良いものを探しています...

于 2012-04-30T12:41:16.257 に答える