更清潔,更可重用的解決方案將作爲附加屬性實現此功能。
使用服務/動作模式:
namespace Control.Services
{
public class UIElementService
{
public static readonly DependencyProperty HandleMouseEventsProperty = DependencyProperty.RegisterAttached("HandleMouseEvents",
typeof(bool), typeof(UIElementService), new FrameworkPropertyMetadata(false, UIElementService.HandleMouseEventsPropertyChanged));
static void HandleMouseEventsPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element == null)
return;
new HandleMouseEventsAction(element);
}
public static bool GetHandleMouseEvents(FrameworkElement target)
{
return (bool)target.GetValue(HandleMouseEventsProperty);
}
public static void SetHandleMouseEvents(FrameworkElement target, bool value)
{
target.SetValue(HandleMouseEventsProperty, value);
}
class HandleMouseEventsAction
{
UIElement m_Target;
MouseButtonEventHandler m_Handler;
internal HandleMouseEventsAction(FrameworkElement source)
{
m_Source = source;
m_Handler = new MouseButtonEventHandler(PreviewMouseLeftButtonUp);
m_Source.Loaded += OnSource_Loaded;
m_Source.Unloaded += OnSource_Unloaded;
}
void OnSource_Loaded(object sender, RoutedEventArgs e)
{
m_Source.AddHandler(Mouse.PreviewMouseUpEvent, m_Handler, true);
}
void OnSource_Unloaded(object sender, RoutedEventArgs e)
{
m_Source.RemoveHandler(Mouse.PreviewMouseUpEvent, m_Handler);
}
void PreviewMouseLeftUIElementUp(object sender, MouseUIElementEventArgs e)
{
e.Handled = true;
}
}
}
}
即可使用,導入命名空間。
<Button sv:UIElementService.HandleMouseEvents="True" />
或
<ContentControl sv:UIElementService.HandleMouseEvents="True">
<Button Content="Click Test" Padding="2" Command="{Binding TestCommand}"/>
</ContentControl>
我沒有測試過這一點(目前沒時間)。我相信即使禁用了該動作仍然會獲得鼠標事件。
HTH,
丹尼斯
謝謝,但我只是在尋找到這一點,我想你可能誤解了我的問題。我不希望外部控件總是*接收事件,我希望它只在點擊位於按鈕外部時才接收事件,即使該按鈕被禁用。 – 2009-11-06 16:01:59
你說得對,我誤解了你的意圖。我會修改。 – 2009-11-06 18:08:24