私の見解モデルが、このバージョンでは、直接対話のワークフローを処理していないので、私は、この問題に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>
これは理想的なソリューションではありません。私はよりエレガントな答えを受け入れます。