2011-07-22 12 views
2

私はフェアアウトパネルを持っています(下図参照)。マウスをパネルエリアから離したときにドッキング解除されていないと表示されなくてはなりません。ユーザーがContextMenuダイアログとドロップダウンリストのためにwpfフライアウトパネルが早すぎるのを防ぐ方法を教えてください。

2)ユーザーがComboBox項目を選択し開き

1):

flyout panel

しかし、私はこれらの条件のいずれかが発生した場合に閉じるようにパネルを望んでいません(上記の図のように)

3)ユーザーの操作によって表示される確認ダイアログ(DataGridの項目を削除するなど)

最初のケースを処理するためにコンテキストメニュー操作(ContextMenuOpeningContextMenuClosingイベント)を追跡するのは簡単ですが、他の2つのケース、特に開かれているトラッキングダイアログを処理する方法がありません。

アイデア?

私のフライアウトパネルは視認性とコンテンツの背後にあるコードで決定されたばかりのグリッドです:

<Grid Name="UndockedGrid" ContextMenuOpening="Grid_ContextMenuOpening" ContextMenuClosing="Grid_ContextMenuClosing" MouseLeave="Grid_MouseLeave"> 
    <!-- Toolbox (undocked) --> 
    <ScrollViewer Name="ToolBoxUndockedViewer"> 
     <StackPanel Name="ToolBoxUndockedPanel" /> 
    </ScrollViewer> 
</Grid> 

答えて

0

私の見解モデルが、このバージョンでは、直接対話のワークフローを処理していないので、私は、この問題にRoutedEventアプローチを取りました。

は、私はデータグリッドコンボボックスのために望んでいた動作を得るために、私は私が追跡したかったルーティングイベントを追加するDataGridを拡張:

public class RoutableDataGrid : DataGrid 
{ 
    public static readonly RoutedEvent ElementOpenedEvent = EventManager.RegisterRoutedEvent("ElementOpened", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RoutableDataGrid)); 

    public event RoutedEventHandler ElementOpened 
    { 
     add { AddHandler(ElementOpenedEvent, value); } 
     remove { RemoveHandler(ElementOpenedEvent, value); } 
    } 

    public static readonly RoutedEvent ElementClosedEvent = EventManager.RegisterRoutedEvent("ElementClosed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RoutableDataGrid)); 

    public event RoutedEventHandler ElementClosed 
    { 
     add { AddHandler(ElementClosedEvent, value); } 
     remove { RemoveHandler(ElementClosedEvent, value); } 
    } 

    public void RaiseElementOpened() 
    { 
     RaiseEvent(new RoutedEventArgs(RoutableDataGrid.ElementOpenedEvent, this)); 
    } 

    public void RaiseElementClosed() 
    { 
     RaiseEvent(new RoutedEventArgs(RoutableDataGrid.ElementClosedEvent, this)); 
    } 
} 

をそしてDataGridComboBoxColumnは、新しいルーティングイベントを発射する拡張されました:

public class BindableDataGridComboBoxColumn : DataGridComboBoxColumn 
{ 
    protected RoutableDataGrid ParentGrid { get; set; } 

    protected FrameworkElement Element { get; set; } 

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) 
    { 
     Element = base.GenerateEditingElement(cell, dataItem); 
     Element.MouseEnter += new System.Windows.Input.MouseEventHandler(element_MouseEnter); 
     Element.MouseLeave += new System.Windows.Input.MouseEventHandler(element_MouseLeave); 
     CopyItemsSource(Element); 
     return Element; 
    } 

    void element_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e) 
    { 
     if (ParentGrid != null) 
     { 
      ParentGrid.RaiseElementClosed(); 
     } 
    } 

    void element_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e) 
    { 
     if (ParentGrid != null) 
     { 
      ParentGrid.RaiseElementOpened(); 
     } 
    } 
} 

MessageBoxが密閉されたクラスであることから、私はMessageBoxを使用してルーティングイベントを発射するラッパークラスを構築しなければならなかった(となるようにXAMLでこの要素のインスタンスを入れて、ハックの詳細それは)ビジュアルツリーにあります:

public class RoutedEventPlaceHolder : UIElement 
{ 
    public static readonly RoutedEvent ElementOpenedEvent = EventManager.RegisterRoutedEvent("ElementOpened", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RoutedEventPlaceHolder)); 

    public event RoutedEventHandler ElementOpened 
    { 
     add { AddHandler(ElementOpenedEvent, value); } 
     remove { RemoveHandler(ElementOpenedEvent, value); } 
    } 

    public static readonly RoutedEvent ElementClosedEvent = EventManager.RegisterRoutedEvent("ElementClosed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RoutedEventPlaceHolder)); 

    public event RoutedEventHandler ElementClosed 
    { 
     add { AddHandler(ElementClosedEvent, value); } 
     remove { RemoveHandler(ElementClosedEvent, value); } 
    } 

    public void RaiseElementOpened() 
    { 
     RaiseEvent(new RoutedEventArgs(RoutedEventPlaceHolder.ElementOpenedEvent, this)); 
    } 

    public void RaiseElementClosed() 
    { 
     RaiseEvent(new RoutedEventArgs(RoutedEventPlaceHolder.ElementClosedEvent, this)); 
    } 

    public MessageBoxResult ShowMessageBox(string text, string caption, MessageBoxButton button) 
    { 
     RaiseElementOpened(); 
     MessageBoxResult result = MessageBox.Show(text, caption, button); 
     RaiseElementClosed(); 
     return result; 
    } 
} 

はその後、最終的に私は、フライアウトパネルで新しいルーティングイベントをサブスクライブすることができます

 <Grid Name="UndockedGrid" lib:RoutedEventPlaceHolder.ElementOpened="Grid_ElementOpened" lib:RoutableDataGrid.ElementOpened="Grid_ElementOpened" ContextMenuOpening="Grid_ContextMenuOpening" ContextMenuClosing="Grid_ContextMenuClosing" MouseLeave="Grid_MouseLeave"> 
      <!-- Toolbox (undocked) --> 
      <ScrollViewer Grid.Row="0" Grid.Column="0" Name="ToolBoxUndockedViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Visibility="Collapsed" MouseLeave="ToolBoxUndockedViewer_MouseLeave"> 
       <StackPanel Name="ToolBoxUndockedPanel" MinWidth="200" Background="{StaticResource ControlBackgroundBrush}" /> 
      </ScrollViewer> 
     </Grid> 

これは理想的なソリューションではありません。私はよりエレガントな答えを受け入れます。

関連する問題