using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using HandyControl.Data; using HandyControl.Interactivity; namespace HandyControl.Controls; public class SearchBar : TextBox, ICommandSource { public SearchBar() { CommandBindings.Add(new CommandBinding(ControlCommands.Search, (s, e) => OnSearchStarted())); } public static readonly RoutedEvent SearchStartedEvent = EventManager.RegisterRoutedEvent("SearchStarted", RoutingStrategy.Bubble, typeof(EventHandler>), typeof(SearchBar)); public event EventHandler> SearchStarted { add => AddHandler(SearchStartedEvent, value); remove => RemoveHandler(SearchStartedEvent, value); } protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if (e.Key == Key.Enter) { OnSearchStarted(); } } protected override void OnTextChanged(TextChangedEventArgs e) { base.OnTextChanged(e); if (IsRealTime) { OnSearchStarted(); } } private void OnSearchStarted() { RaiseEvent(new FunctionEventArgs(SearchStartedEvent, this) { Info = Text }); switch (Command) { case null: return; case RoutedCommand command: command.Execute(CommandParameter, CommandTarget); break; default: Command.Execute(CommandParameter); break; } } /// /// 是否实时搜索 /// public static readonly DependencyProperty IsRealTimeProperty = DependencyProperty.Register( nameof(IsRealTime), typeof(bool), typeof(SearchBar), new PropertyMetadata(ValueBoxes.FalseBox)); /// /// 是否实时搜索 /// public bool IsRealTime { get => (bool) GetValue(IsRealTimeProperty); set => SetValue(IsRealTimeProperty, ValueBoxes.BooleanBox(value)); } public static readonly DependencyProperty CommandProperty = DependencyProperty.Register( nameof(Command), typeof(ICommand), typeof(SearchBar), new PropertyMetadata(default(ICommand), OnCommandChanged)); private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var ctl = (SearchBar) d; if (e.OldValue is ICommand oldCommand) { oldCommand.CanExecuteChanged -= ctl.CanExecuteChanged; } if (e.NewValue is ICommand newCommand) { newCommand.CanExecuteChanged += ctl.CanExecuteChanged; } } public ICommand Command { get => (ICommand) GetValue(CommandProperty); set => SetValue(CommandProperty, value); } public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register( nameof(CommandParameter), typeof(object), typeof(SearchBar), new PropertyMetadata(default(object))); public object CommandParameter { get => GetValue(CommandParameterProperty); set => SetValue(CommandParameterProperty, value); } public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register( nameof(CommandTarget), typeof(IInputElement), typeof(SearchBar), new PropertyMetadata(default(IInputElement))); public IInputElement CommandTarget { get => (IInputElement) GetValue(CommandTargetProperty); set => SetValue(CommandTargetProperty, value); } private void CanExecuteChanged(object sender, EventArgs e) { if (Command == null) return; IsEnabled = Command is RoutedCommand command ? command.CanExecute(CommandParameter, CommandTarget) : Command.CanExecute(CommandParameter); } }