我有一个SearchTextBox
自定义控件,如图所示:
当鼠标点击它时,该标签消失。如果用户单击并且没有文本,则标签会重新出现(如果用户单击但是在那里留下文本,则文本保留并且标签保持隐藏状态)。当用户开始输入时,此按钮将替换图像:
当用户点击该按钮时,文本将被清除。
这一切都正常。我所说的奇怪的行为是,当点击清除按钮时,标签在控制器上闪烁一瞬间才消失(它应该在整个时间内保持隐藏状态)。由于XAML中的Multitrigger
使用IsFocused
,我想也许我可以通过在Focus()
事件完成之前在代码隐藏中调用Click
来解决问题。这似乎有点hacky,但它确实有效。我的问题是,为什么我必须这样做才能让它发挥作用"对吧?"
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:
public class SearchTextBox : TextBox
{
public static readonly DependencyProperty LabelTextProperty;
public static readonly DependencyProperty LabelTextColorProperty;
public static readonly DependencyProperty HasTextProperty;
private static readonly DependencyPropertyKey HasTextPropertyKey;
public static readonly DependencyProperty SourceProperty;
private static readonly DependencyProperty IsMouseLeftButtonDownProperty;
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));
HasTextPropertyKey = DependencyProperty.RegisterReadOnly("HasText", typeof(bool), typeof(SearchTextBox), new PropertyMetadata());
HasTextProperty = HasTextPropertyKey.DependencyProperty;
SourceProperty = DependencyProperty.Register("Source", typeof(ImageSource), typeof(SearchTextBox));
IsMouseLeftButtonDownProperty = DependencyProperty.Register("IsMouseLeftButtonDown", typeof(bool), typeof(SearchTextBox), new PropertyMetadata());
}
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 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 bool IsMouseLeftButtonDown
{
get { return (bool)GetValue(IsMouseLeftButtonDownProperty); }
private set { SetValue(IsMouseLeftButtonDownProperty, value); }
}
public override void OnApplyTemplate()
{
Button b = GetTemplateChild("PART_Button") as Button;
if (b != null)
{
b.Click += OnClick;
}
base.OnApplyTemplate();
}
private void OnClick(object sender, RoutedEventArgs e)
{
Text = "";
Focus();
e.Handled = true;
}
}
答案 0 :(得分:1)
闪烁最有可能发生,因为如果您按下它,焦点会从您的控件移动到清除按钮。 您可以解决这个问题,即使清除按钮不可聚焦,即
<Button x:Name="PART_Button" Focusable="False" ... />
然后按下按钮时焦点不会移动。