我明白,如果我试图冒泡或隧道事件到另一个控件,按钮会"窃取"事件,但它是实际的按钮本身,我试图调用事件。在这些文件中不应该有任何不同寻常的东西,但以防万一,这里是整个事情(问题是在SearchTextBox.cs中的OnApplyTemplate):
Generic.xaml:
<SolidColorBrush x:Key="TextBoxBorder" Color="#ababab"/>
<Style TargetType="{x:Type ui:SearchTextBox}">
<Setter Property="AllowDrop" Value="True" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="LabelText" Value="Search for..." />
<Setter Property="LabelTextColor" Value="Gray" />
<Setter Property="Padding" Value="1" />
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ui:SearchTextBox}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}" />
</Grid.ColumnDefinitions>
<Label x:Name="LabelText"
Grid.Column="0"
Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LabelTextColor}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LabelText}"
Padding="0"
Margin="5,0,0,0"
FontStyle="Italic"
VerticalAlignment="Center"
Visibility="Hidden" />
<ScrollViewer Grid.Column="0" Panel.ZIndex="1" x:Name="PART_ContentHost" Background="{TemplateBinding Background}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Margin="5,0,0,0" Padding="0"/>
<Image x:Name="Image" Grid.Column="1" Visibility="Hidden" Source="search2.png" Width="15" Height="15" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button x:Name="PART_Button" Grid.Column="1" Width="15" Height="15">
<Border HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Source="searchstop.png" />
</Border>
</Button>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Text" Value="">
<Setter TargetName="Image" Property="Visibility" Value="Visible" />
<Setter TargetName="PART_Button" Property="Visibility" Value="Hidden" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value="" />
<Condition Property="IsFocused" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="LabelText" Property="Visibility" Value="Visible" />
<Setter TargetName="PART_ContentHost" Property="Visibility" Value="Hidden" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
SearchTextBox.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace App
{
public class SearchTextBox : TextBox
{
public static readonly DependencyProperty LabelTextProperty;
public static readonly DependencyProperty LabelTextColorProperty;
public static readonly DependencyProperty SearchModeProperty;
public static readonly DependencyProperty HasTextProperty;
private static readonly DependencyPropertyKey HasTextPropertyKey;
public static readonly DependencyProperty SourceProperty;
static SearchTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(SearchTextBox), new FrameworkPropertyMetadata(typeof(SearchTextBox)));
LabelTextProperty = DependencyProperty.Register("LabelText", typeof(string), typeof(SearchTextBox));
LabelTextColorProperty = DependencyProperty.Register("LabelTextColor", typeof(Brush), typeof(SearchTextBox));
SearchModeProperty = DependencyProperty.Register("SearchMode", typeof(SearchMode), typeof(SearchTextBox), new PropertyMetadata(SearchMode.Instant));
HasTextPropertyKey = DependencyProperty.RegisterReadOnly("HasText", typeof(bool), typeof(SearchTextBox), new PropertyMetadata());
HasTextProperty = HasTextPropertyKey.DependencyProperty;
SourceProperty = DependencyProperty.Register("Source", typeof(ImageSource), typeof(SearchTextBox));
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
HasText = Text.Length != 0;
}
public string LabelText
{
get { return (string)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
public Brush LabelTextColor
{
get { return (Brush)GetValue(LabelTextColorProperty); }
set { SetValue(LabelTextColorProperty, value); }
}
public SearchMode SearchMode
{
get { return (SearchMode)GetValue(SearchModeProperty); }
set { SetValue(SearchModeProperty, value); }
}
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
public bool HasText
{
get { return (bool)GetValue(HasTextProperty); }
private set { SetValue(HasTextPropertyKey, value); }
}
public override void OnApplyTemplate()
{
Button b = GetTemplateChild("PART_Button") as Button;
if (b != null)
{
b.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(OnMouseLeftButtonDown);
// This also works
//b.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(OnMouseLeftButtonDown));
// Doesn't work
//b.MouseLeftButtonDown += new MouseButtonEventHandler(OnMouseLeftButtonDown);
}
base.OnApplyTemplate();
}
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Text = "";
}
}
}
试着读一下:
http://msdn.microsoft.com/en-us/library/system.windows.uielement.mouseleftbuttondown.aspx
MouseLeftButtonDownEvent由另一个控件处理,通常是ButtonBase:
http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/Primitives/ButtonBase.cs#1001a15c43ab91f9(第414行)
正确的方法是使用AddHandler或PreviewMouseLeftButtonDown事件