diff --git a/HandyControl/Controls/Input/ComboBox.cs b/HandyControl/Controls/Input/ComboBox.cs
index 3eb05716..7d6baf16 100644
--- a/HandyControl/Controls/Input/ComboBox.cs
+++ b/HandyControl/Controls/Input/ComboBox.cs
@@ -33,7 +33,7 @@ namespace HandyControl.Controls
/// 数据是否错误
///
public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register(
- "IsError", typeof(bool), typeof(ComboBox), new PropertyMetadata(default(bool)));
+ "IsError", typeof(bool), typeof(ComboBox), new PropertyMetadata(ValueBoxes.FalseBox));
public bool IsError
{
@@ -72,7 +72,7 @@ namespace HandyControl.Controls
/// 是否显示清除按钮
///
public static readonly DependencyProperty ShowClearButtonProperty = DependencyProperty.Register(
- "ShowClearButton", typeof(bool), typeof(ComboBox), new PropertyMetadata(default(bool)));
+ "ShowClearButton", typeof(bool), typeof(ComboBox), new PropertyMetadata(ValueBoxes.FalseBox));
public bool ShowClearButton
{
diff --git a/HandyControl/Controls/Input/PasswordBox.cs b/HandyControl/Controls/Input/PasswordBox.cs
index 392fda2e..8d7708e2 100644
--- a/HandyControl/Controls/Input/PasswordBox.cs
+++ b/HandyControl/Controls/Input/PasswordBox.cs
@@ -27,7 +27,7 @@ namespace HandyControl.Controls
/// 数据是否错误
///
public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register(
- "IsError", typeof(bool), typeof(PasswordBox), new PropertyMetadata(default(bool)));
+ "IsError", typeof(bool), typeof(PasswordBox), new PropertyMetadata(ValueBoxes.FalseBox));
///
/// 错误提示
@@ -45,7 +45,7 @@ namespace HandyControl.Controls
/// 是否显示清除按钮
///
public static readonly DependencyProperty ShowClearButtonProperty = DependencyProperty.Register(
- "ShowClearButton", typeof(bool), typeof(PasswordBox), new PropertyMetadata(default(bool)));
+ "ShowClearButton", typeof(bool), typeof(PasswordBox), new PropertyMetadata(ValueBoxes.FalseBox));
private string _password;
diff --git a/HandyControl/Controls/Input/SearchBar.cs b/HandyControl/Controls/Input/SearchBar.cs
new file mode 100644
index 00000000..cc19ed54
--- /dev/null
+++ b/HandyControl/Controls/Input/SearchBar.cs
@@ -0,0 +1,175 @@
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+using HandyControl.Data;
+using HandyControl.Interactivity;
+using HandyControl.Tools;
+
+namespace HandyControl.Controls
+{
+ [TemplatePart(Name = ElementTextBox, Type = typeof(WatermarkTextBox))]
+ public class SearchBar : Control, IDataInput
+ {
+ private const string ElementTextBox = "PART_TextBox";
+
+ private WatermarkTextBox _textBox;
+
+ public Func> VerifyFunc { get; set; }
+
+ public SearchBar()
+ {
+ CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) =>
+ {
+ _textBox.Text = string.Empty;
+ }));
+ CommandBindings.Add(new CommandBinding(ControlCommands.Search, (s, e) =>
+ {
+ RaiseEvent(new FunctionEventArgs(SearchStartedEvent, this)
+ {
+ Source = Text
+ });
+ }));
+ }
+
+ public static readonly RoutedEvent SearchStartedEvent =
+ EventManager.RegisterRoutedEvent("SearchStarted", RoutingStrategy.Direct,
+ typeof(EventHandler>), typeof(SearchBar));
+
+ public event EventHandler> SearchStarted
+ {
+ add => AddHandler(SearchStartedEvent, value);
+ remove => RemoveHandler(SearchStartedEvent, value);
+ }
+
+ public override void OnApplyTemplate()
+ {
+ if (_textBox != null)
+ {
+ _textBox.TextChanged -= TextBox_TextChanged;
+ }
+
+ base.OnApplyTemplate();
+
+ _textBox = GetTemplateChild(ElementTextBox) as WatermarkTextBox;
+ if (_textBox != null)
+ {
+ SetBinding(TextProperty, new Binding(TextProperty.Name)
+ {
+ Source = _textBox,
+ Mode = BindingMode.TwoWay,
+ UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+ });
+ _textBox.TextChanged += TextBox_TextChanged;
+ _textBox.KeyDown += TextBox_KeyDown;
+ }
+ }
+
+ private void TextBox_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Enter)
+ {
+ RaiseEvent(new FunctionEventArgs(SearchStartedEvent, this)
+ {
+ Source = Text
+ });
+ }
+ }
+
+ private void TextBox_TextChanged(object sender, TextChangedEventArgs e) => VerifyData();
+
+ public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
+ "Text", typeof(string), typeof(SearchBar), new PropertyMetadata(default(string)));
+
+ public string Text
+ {
+ get => (string) GetValue(TextProperty);
+ set => SetValue(TextProperty, value);
+ }
+
+ ///
+ /// 数据是否错误
+ ///
+ public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register(
+ "IsError", typeof(bool), typeof(SearchBar), new PropertyMetadata(ValueBoxes.FalseBox));
+
+ public bool IsError
+ {
+ get => (bool)GetValue(IsErrorProperty);
+ set => SetValue(IsErrorProperty, value);
+ }
+
+ ///
+ /// 错误提示
+ ///
+ public static readonly DependencyProperty ErrorStrProperty = DependencyProperty.Register(
+ "ErrorStr", typeof(string), typeof(SearchBar), new PropertyMetadata(default(string)));
+
+ public string ErrorStr
+ {
+ get => (string)GetValue(ErrorStrProperty);
+ set => SetValue(ErrorStrProperty, value);
+ }
+
+ ///
+ /// 文本类型
+ ///
+ public static readonly DependencyProperty TextTypeProperty = DependencyProperty.Register(
+ "TextType", typeof(TextType), typeof(SearchBar), new PropertyMetadata(default(TextType)));
+
+ public TextType TextType
+ {
+ get => (TextType) GetValue(TextTypeProperty);
+ set => SetValue(TextTypeProperty, value);
+ }
+
+ ///
+ /// 是否显示清除按钮
+ ///
+ public static readonly DependencyProperty ShowClearButtonProperty = DependencyProperty.Register(
+ "ShowClearButton", typeof(bool), typeof(SearchBar), new PropertyMetadata(ValueBoxes.FalseBox));
+
+ public bool ShowClearButton
+ {
+ get => (bool)GetValue(ShowClearButtonProperty);
+ set => SetValue(ShowClearButtonProperty, value);
+ }
+
+ public virtual bool VerifyData()
+ {
+ OperationResult result;
+
+ if (VerifyFunc != null)
+ {
+ result = VerifyFunc.Invoke(Text);
+ }
+ else
+ {
+ if (!string.IsNullOrEmpty(Text))
+ {
+ if (TextType != TextType.Common)
+ {
+ result = Text.IsKindOf(TextType) ? OperationResult.Success() : OperationResult.Failed(Properties.Langs.Lang.FormatError);
+ }
+ else
+ {
+ result = OperationResult.Success();
+ }
+ }
+ else if (InfoElement.GetNecessary(this))
+ {
+ result = OperationResult.Failed(Properties.Langs.Lang.IsNecessary);
+ }
+ else
+ {
+ result = OperationResult.Success();
+ }
+ }
+
+ IsError = !result.Data;
+ ErrorStr = result.Message;
+ return result.Data;
+ }
+ }
+}
\ No newline at end of file
diff --git a/HandyControl/HandyControl.csproj b/HandyControl/HandyControl.csproj
index ef651cad..fcc5cbc6 100644
--- a/HandyControl/HandyControl.csproj
+++ b/HandyControl/HandyControl.csproj
@@ -49,6 +49,7 @@
+
@@ -267,6 +268,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -479,6 +484,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/HandyControl/Interactivity/ControlCommands.cs b/HandyControl/Interactivity/ControlCommands.cs
index 2f57807a..e74368fc 100644
--- a/HandyControl/Interactivity/ControlCommands.cs
+++ b/HandyControl/Interactivity/ControlCommands.cs
@@ -7,6 +7,11 @@ namespace HandyControl.Interactivity
///
public static class ControlCommands
{
+ ///
+ /// 搜索
+ ///
+ public static RoutedCommand Search { get; } = new RoutedCommand(nameof(Search), typeof(ControlCommands));
+
///
/// 清除
///
diff --git a/HandyControl/Themes/Styles/Base/SearchBarBaseStyle.xaml b/HandyControl/Themes/Styles/Base/SearchBarBaseStyle.xaml
new file mode 100644
index 00000000..8a6cd520
--- /dev/null
+++ b/HandyControl/Themes/Styles/Base/SearchBarBaseStyle.xaml
@@ -0,0 +1,263 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HandyControl/Themes/Styles/SearchBar.xaml b/HandyControl/Themes/Styles/SearchBar.xaml
new file mode 100644
index 00000000..05cb7ed0
--- /dev/null
+++ b/HandyControl/Themes/Styles/SearchBar.xaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HandyControl/Themes/Styles/Style.xaml b/HandyControl/Themes/Styles/Style.xaml
index 35f9dabb..ff34cde4 100644
--- a/HandyControl/Themes/Styles/Style.xaml
+++ b/HandyControl/Themes/Styles/Style.xaml
@@ -44,6 +44,7 @@
+
\ No newline at end of file
diff --git a/HandyControlDemo/Data/MessageToken.cs b/HandyControlDemo/Data/MessageToken.cs
index fd0ce471..c282e7d0 100644
--- a/HandyControlDemo/Data/MessageToken.cs
+++ b/HandyControlDemo/Data/MessageToken.cs
@@ -50,6 +50,8 @@
public static readonly string CalendarWithClockDemoCtl = nameof(CalendarWithClockDemoCtl);
+ public static readonly string SearchBarDemoCtl = nameof(SearchBarDemoCtl);
+
public static readonly string ButtonDemoCtl = nameof(ButtonDemoCtl);
public static readonly string ToggleButtonDemoCtl = nameof(ToggleButtonDemoCtl);
diff --git a/HandyControlDemo/Data/MessageToken.tt b/HandyControlDemo/Data/MessageToken.tt
index 8d6d728b..fabdaf40 100644
--- a/HandyControlDemo/Data/MessageToken.tt
+++ b/HandyControlDemo/Data/MessageToken.tt
@@ -27,7 +27,8 @@ var controlList = new List
"PasswordBoxDemoCtl",
"DatePickerDemoCtl",
"DateTimePickerDemoCtl",
- "CalendarWithClockDemoCtl"
+ "CalendarWithClockDemoCtl",
+ "SearchBarDemoCtl"
};
var styleList = new List
{
diff --git a/HandyControlDemo/HandyControlDemo.csproj b/HandyControlDemo/HandyControlDemo.csproj
index c07458a4..e29a40ea 100644
--- a/HandyControlDemo/HandyControlDemo.csproj
+++ b/HandyControlDemo/HandyControlDemo.csproj
@@ -150,6 +150,9 @@
ScrollViewerDemoCtl.xaml
+
+ SearchBarDemoCtl.xaml
+
StepBarDemoCtl.xaml
@@ -405,6 +408,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -585,6 +592,7 @@
TextTemplatingFileGenerator
MessageToken.cs
+
diff --git a/HandyControlDemo/Properties/Langs/Lang.Designer.cs b/HandyControlDemo/Properties/Langs/Lang.Designer.cs
index 7d02a48c..8a5cb41d 100644
--- a/HandyControlDemo/Properties/Langs/Lang.Designer.cs
+++ b/HandyControlDemo/Properties/Langs/Lang.Designer.cs
@@ -249,6 +249,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
+ ///
+ /// 查找类似 一般 的本地化字符串。
+ ///
+ public static string Common {
+ get {
+ return ResourceManager.GetString("Common", resourceCulture);
+ }
+ }
+
///
/// 查找类似 对比滑块 的本地化字符串。
///
@@ -744,6 +753,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
+ ///
+ /// 查找类似 搜索栏 的本地化字符串。
+ ///
+ public static string SearchBar {
+ get {
+ return ResourceManager.GetString("SearchBar", resourceCulture);
+ }
+ }
+
///
/// 查找类似 选中 的本地化字符串。
///
@@ -753,6 +771,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
+ ///
+ /// 查找类似 显示行号 的本地化字符串。
+ ///
+ public static string ShowRowNumber {
+ get {
+ return ResourceManager.GetString("ShowRowNumber", resourceCulture);
+ }
+ }
+
///
/// 查找类似 滑块 的本地化字符串。
///
diff --git a/HandyControlDemo/Properties/Langs/Lang.en.resx b/HandyControlDemo/Properties/Langs/Lang.en.resx
index e25695e0..582185a9 100644
--- a/HandyControlDemo/Properties/Langs/Lang.en.resx
+++ b/HandyControlDemo/Properties/Langs/Lang.en.resx
@@ -417,4 +417,13 @@
ToolBar
+
+ Common
+
+
+ ShowRowNumber
+
+
+ SearchBar
+
\ No newline at end of file
diff --git a/HandyControlDemo/Properties/Langs/Lang.resx b/HandyControlDemo/Properties/Langs/Lang.resx
index 5db2c98a..1e2fe228 100644
--- a/HandyControlDemo/Properties/Langs/Lang.resx
+++ b/HandyControlDemo/Properties/Langs/Lang.resx
@@ -397,4 +397,13 @@
工具条
+
+ 一般
+
+
+ 显示行号
+
+
+ 搜索栏
+
\ No newline at end of file
diff --git a/HandyControlDemo/Resources/Img/LeftMainContent/Search_16x.png b/HandyControlDemo/Resources/Img/LeftMainContent/Search_16x.png
new file mode 100644
index 00000000..042a1c42
Binary files /dev/null and b/HandyControlDemo/Resources/Img/LeftMainContent/Search_16x.png differ
diff --git a/HandyControlDemo/UserControl/Controls/SearchBarDemoCtl.xaml b/HandyControlDemo/UserControl/Controls/SearchBarDemoCtl.xaml
new file mode 100644
index 00000000..3159c30f
--- /dev/null
+++ b/HandyControlDemo/UserControl/Controls/SearchBarDemoCtl.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/HandyControlDemo/UserControl/Controls/SearchBarDemoCtl.xaml.cs b/HandyControlDemo/UserControl/Controls/SearchBarDemoCtl.xaml.cs
new file mode 100644
index 00000000..0375fd53
--- /dev/null
+++ b/HandyControlDemo/UserControl/Controls/SearchBarDemoCtl.xaml.cs
@@ -0,0 +1,10 @@
+namespace HandyControlDemo.UserControl
+{
+ public partial class SearchBarDemoCtl
+ {
+ public SearchBarDemoCtl()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/HandyControlDemo/UserControl/Controls/TextBoxDemoCtl.xaml.cs b/HandyControlDemo/UserControl/Controls/TextBoxDemoCtl.xaml.cs
index 9740a22c..f68246b0 100644
--- a/HandyControlDemo/UserControl/Controls/TextBoxDemoCtl.xaml.cs
+++ b/HandyControlDemo/UserControl/Controls/TextBoxDemoCtl.xaml.cs
@@ -1,5 +1,4 @@
-// ReSharper disable once CheckNamespace
-namespace HandyControlDemo.UserControl
+namespace HandyControlDemo.UserControl
{
public partial class TextBoxDemoCtl
{
diff --git a/HandyControlDemo/UserControl/Main/LeftMainContent.xaml b/HandyControlDemo/UserControl/Main/LeftMainContent.xaml
index 1645bf92..ca639d83 100644
--- a/HandyControlDemo/UserControl/Main/LeftMainContent.xaml
+++ b/HandyControlDemo/UserControl/Main/LeftMainContent.xaml
@@ -125,12 +125,12 @@
-
+
-
+
@@ -189,6 +189,11 @@
+
+
+
+
+
diff --git a/HandyControlDemo/UserControl/Styles/DataGridDemoCtl.xaml b/HandyControlDemo/UserControl/Styles/DataGridDemoCtl.xaml
index 732230ba..da9007c0 100644
--- a/HandyControlDemo/UserControl/Styles/DataGridDemoCtl.xaml
+++ b/HandyControlDemo/UserControl/Styles/DataGridDemoCtl.xaml
@@ -7,7 +7,7 @@
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl">
-
+
@@ -30,7 +30,7 @@
-
+