diff --git a/src/Avalonia/Directory.Build.props b/src/Avalonia/Directory.Build.props
index 9ed3221f9..336c213bd 100644
--- a/src/Avalonia/Directory.Build.props
+++ b/src/Avalonia/Directory.Build.props
@@ -1,8 +1,8 @@
-
+
enable
latest
net9.0
- 11.3.6
+ 12.0.1
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/App.axaml.cs b/src/Avalonia/HandyControlDemo_Avalonia/App.axaml.cs
index 78d6b88ed..90d3ab92c 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/App.axaml.cs
+++ b/src/Avalonia/HandyControlDemo_Avalonia/App.axaml.cs
@@ -18,7 +18,6 @@ public override void Initialize()
public override void OnFrameworkInitializationCompleted()
{
Properties.Langs.Lang.Culture = new CultureInfo("en");
- RemoveDefaultDataValidator();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
@@ -27,17 +26,4 @@ public override void OnFrameworkInitializationCompleted()
base.OnFrameworkInitializationCompleted();
}
-
- private static void RemoveDefaultDataValidator()
- {
- // Get an array of plugins to remove
- var dataValidationPluginsToRemove =
- BindingPlugins.DataValidators.OfType().ToArray();
-
- // remove each entry found
- foreach (var plugin in dataValidationPluginsToRemove)
- {
- BindingPlugins.DataValidators.Remove(plugin);
- }
- }
}
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/HandyControlDemo_Avalonia.csproj b/src/Avalonia/HandyControlDemo_Avalonia/HandyControlDemo_Avalonia.csproj
index 569b95451..06e25f1be 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/HandyControlDemo_Avalonia.csproj
+++ b/src/Avalonia/HandyControlDemo_Avalonia/HandyControlDemo_Avalonia.csproj
@@ -29,6 +29,10 @@
+
+ None
+ All
+
@@ -44,6 +48,12 @@
True
Lang.resx
+
+ SearchBarDemo.axaml
+
+
+ WindowDemo.axaml
+
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/Program.cs b/src/Avalonia/HandyControlDemo_Avalonia/Program.cs
index 8cc817a5d..94ee99f08 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/Program.cs
+++ b/src/Avalonia/HandyControlDemo_Avalonia/Program.cs
@@ -12,5 +12,8 @@ public static void Main(string[] args) => BuildAvaloniaApp()
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure()
.UsePlatformDetect()
+#if DEBUG
+ .WithDeveloperTools()
+#endif
.LogToTrace();
}
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Main/LeftMainContent.axaml b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Main/LeftMainContent.axaml
index 58cb4fb21..ed917abb2 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Main/LeftMainContent.axaml
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Main/LeftMainContent.axaml
@@ -3,6 +3,8 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:HandyControlDemo.Data"
+ xmlns:vm="using:HandyControlDemo.ViewModel"
+ x:DataType="{x:Type vm:MainViewModel}"
Margin="16,16,0,16"
CornerRadius="10"
Effect="{StaticResource EffectShadow4}">
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Main/MainContent.axaml b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Main/MainContent.axaml
index 7f72e59aa..4fb52c327 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Main/MainContent.axaml
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Main/MainContent.axaml
@@ -1,5 +1,7 @@
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/AutoCompleteBoxDemo.axaml b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/AutoCompleteBoxDemo.axaml
index 22686e938..1a6bc501f 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/AutoCompleteBoxDemo.axaml
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/AutoCompleteBoxDemo.axaml
@@ -1,6 +1,8 @@
-
-
-
-
+ x:DataType="vm:InputElementDemoViewModel"
+ x:CompileBindings="False"
+ DataContext="{Binding InputElementDemo, Source={x:Static vm:ViewModelLocator.Instance}}"
+ >
+
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/ListBoxDemo.axaml b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/ListBoxDemo.axaml
index 4e0bffac3..1b112bb84 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/ListBoxDemo.axaml
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/ListBoxDemo.axaml
@@ -1,5 +1,7 @@
-
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/NumericUpDownDemo.axaml b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/NumericUpDownDemo.axaml
index 677d506c9..527158dbe 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/NumericUpDownDemo.axaml
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/NumericUpDownDemo.axaml
@@ -1,8 +1,10 @@
-
@@ -36,7 +38,7 @@
Value="10000"
Width="380"
hc:TitleElement.TitleWidth="140"
- Watermark="Please enter content"
+ PlaceholderText="Please enter content"
hc:TitleElement.TitlePlacement="Left"
hc:TitleElement.Title="The title is on the left"
Theme="{StaticResource NumericUpDownExtend}"
@@ -59,7 +61,7 @@
hc:TitleElement.Title="This is the title"
Theme="{StaticResource NumericUpDownExtend}" />
@@ -74,7 +76,7 @@
hc:InfoElement.ShowClearButton="True"
Width="380"
hc:TitleElement.TitleWidth="140"
- Watermark="Please enter content"
+ PlaceholderText="Please enter content"
hc:TitleElement.TitlePlacement="Left"
hc:TitleElement.Title="The title is on the left"
Theme="{StaticResource NumericUpDownExtend}"
@@ -96,7 +98,7 @@
hc:TitleElement.Title="This is the title"
Theme="{StaticResource NumericUpDownExtend.Small}" />
@@ -111,7 +113,7 @@
Value="10000"
Width="380"
hc:TitleElement.TitleWidth="140"
- Watermark="Please enter content"
+ PlaceholderText="Please enter content"
hc:TitleElement.TitlePlacement="Left"
hc:TitleElement.Title="The title is on the left"
Theme="{StaticResource NumericUpDownExtend.Small}"
@@ -134,7 +136,7 @@
hc:TitleElement.Title="This is the title"
Theme="{StaticResource NumericUpDownExtend.Small}" />
@@ -149,7 +151,7 @@
hc:InfoElement.ShowClearButton="True"
Width="380"
hc:TitleElement.TitleWidth="140"
- Watermark="Please enter content"
+ PlaceholderText="Please enter content"
hc:TitleElement.TitlePlacement="Left"
hc:TitleElement.Title="The title is on the left"
Theme="{StaticResource NumericUpDownExtend.Small}"
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/SearchBarDemo.axaml b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/SearchBarDemo.axaml
new file mode 100644
index 000000000..404ab7063
--- /dev/null
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/SearchBarDemo.axaml
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/SearchBarDemo.axaml.cs b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/SearchBarDemo.axaml.cs
new file mode 100644
index 000000000..0e5b2a31e
--- /dev/null
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/SearchBarDemo.axaml.cs
@@ -0,0 +1,17 @@
+using System.Threading.Tasks;
+using Avalonia.Data;
+using Avalonia.Interactivity;
+using HandyControl.Controls;
+using HandyControl.Data;
+
+namespace HandyControlDemo.UserControl;
+
+public partial class SearchBarDemo : Avalonia.Controls.UserControl
+{
+ public SearchBarDemo()
+ {
+ InitializeComponent();
+ }
+
+}
+
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/TextBoxDemo.axaml b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/TextBoxDemo.axaml
index ba4536835..0eabdd4a3 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/TextBoxDemo.axaml
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/TextBoxDemo.axaml
@@ -1,8 +1,10 @@
-
-
-
+
+
+
+
+
+
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/WindowDemo.axaml.cs b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/WindowDemo.axaml.cs
new file mode 100644
index 000000000..957ac0e15
--- /dev/null
+++ b/src/Avalonia/HandyControlDemo_Avalonia/UserControl/Styles/WindowDemo.axaml.cs
@@ -0,0 +1,21 @@
+using System.Threading.Tasks;
+using Avalonia.Interactivity;
+using HandyControl.Controls;
+using HandyControl.Data;
+
+namespace HandyControlDemo.UserControl;
+
+public partial class WindowDemo : Avalonia.Controls.UserControl
+{
+ public WindowDemo()
+ {
+ InitializeComponent();
+ }
+
+
+ private async void ButtonMessage_OnClick(object sender, RoutedEventArgs e)
+ {
+ await MessageBox.Show(Properties.Langs.Lang.GrowlAsk, Properties.Langs.Lang.Title, MessageBoxButton.YesNo, MessageBoxImage.Question);
+ }
+}
+
diff --git a/src/Avalonia/HandyControlDemo_Avalonia/ViewModel/Common/InputElementDemoViewModel.cs b/src/Avalonia/HandyControlDemo_Avalonia/ViewModel/Common/InputElementDemoViewModel.cs
index 3fe76999a..91c702450 100644
--- a/src/Avalonia/HandyControlDemo_Avalonia/ViewModel/Common/InputElementDemoViewModel.cs
+++ b/src/Avalonia/HandyControlDemo_Avalonia/ViewModel/Common/InputElementDemoViewModel.cs
@@ -1,7 +1,10 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
+using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using HandyControl.Controls;
using HandyControlDemo.Properties.Langs;
using HandyControlDemo.Tools.Converter;
@@ -43,4 +46,10 @@ private static List GetComboBoxDemoDataList()
return list;
}
+
+ [RelayCommand]
+ private static async Task Search(string key)
+ {
+ await MessageBox.Info(key);
+ }
}
diff --git a/src/Avalonia/HandyControl_Avalonia/Controls/Attach/InfoElement.cs b/src/Avalonia/HandyControl_Avalonia/Controls/Attach/InfoElement.cs
index 53ea4c72c..2859e0a0e 100644
--- a/src/Avalonia/HandyControl_Avalonia/Controls/Attach/InfoElement.cs
+++ b/src/Avalonia/HandyControl_Avalonia/Controls/Attach/InfoElement.cs
@@ -2,8 +2,16 @@
namespace HandyControl.Controls;
-public class InfoElement
+public class InfoElement : AvaloniaObject
{
+ public static readonly AttachedProperty PlaceholderProperty =
+ AvaloniaProperty.RegisterAttached("Placeholder", inherits: true);
+
+ public static void SetPlaceholder(AvaloniaObject element, string value) => element.SetValue(PlaceholderProperty, value);
+
+ public static string GetPlaceholder(AvaloniaObject element) => element.GetValue(PlaceholderProperty);
+
+
public static readonly AttachedProperty NecessaryProperty =
AvaloniaProperty.RegisterAttached("Necessary", inherits: true);
diff --git a/src/Avalonia/HandyControl_Avalonia/Controls/Attach/TitleElement.cs b/src/Avalonia/HandyControl_Avalonia/Controls/Attach/TitleElement.cs
index ed95a7ad2..bba9061af 100644
--- a/src/Avalonia/HandyControl_Avalonia/Controls/Attach/TitleElement.cs
+++ b/src/Avalonia/HandyControl_Avalonia/Controls/Attach/TitleElement.cs
@@ -6,7 +6,7 @@
namespace HandyControl.Controls;
-public class TitleElement
+public class TitleElement: AvaloniaObject
{
public static readonly AttachedProperty TitleProperty =
AvaloniaProperty.RegisterAttached("Title");
diff --git a/src/Avalonia/HandyControl_Avalonia/Controls/Input/SearchBar.cs b/src/Avalonia/HandyControl_Avalonia/Controls/Input/SearchBar.cs
new file mode 100644
index 000000000..24e4e1397
--- /dev/null
+++ b/src/Avalonia/HandyControl_Avalonia/Controls/Input/SearchBar.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Windows.Input;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Data.Converters;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using HandyControl.Data;
+
+namespace HandyControl.Controls;
+
+public class SearchBar : TextBox, ICommandSource
+{
+ public static readonly RoutedEvent SearchStartedEvent = RoutedEvent.Register>("SearchStarted", RoutingStrategies.Bubble);
+
+ 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 OnTextInput(TextInputEventArgs e)
+ {
+ base.OnTextInput(e);
+
+ if (IsRealTime)
+ {
+ OnSearchStarted();
+ }
+ }
+
+ private void OnSearchStarted()
+ {
+ RaiseEvent(new FunctionEventArgs(SearchStartedEvent, this)
+ {
+ Info = Text
+ });
+
+ switch (Command)
+ {
+ case null:
+ return;
+ default:
+ Command.Execute(CommandParameter);
+ break;
+ }
+ }
+
+ ///
+ /// 是否实时搜索
+ ///
+ public static readonly StyledProperty IsRealTimeProperty = AvaloniaProperty.Register(nameof(IsRealTime), false);
+
+
+ ///
+ /// 是否实时搜索
+ ///
+ public bool IsRealTime
+ {
+ get => (bool)GetValue(IsRealTimeProperty);
+ set => SetValue(IsRealTimeProperty, ValueBoxes.BooleanBox(value));
+ }
+
+ public static readonly StyledProperty CommandProperty = AvaloniaProperty.Register(nameof(Command));
+
+
+ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
+ {
+ base.OnPropertyChanged(change);
+ if (change.Property == CommandProperty)
+ {
+ OnCommandChanged(change);
+ }
+ }
+
+ private void OnCommandChanged(AvaloniaPropertyChangedEventArgs e)
+ {
+ if (e.OldValue is ICommand oldCommand)
+ {
+ oldCommand.CanExecuteChanged -= CanExecuteChanged;
+ }
+ if (e.NewValue is ICommand newCommand)
+ {
+ newCommand.CanExecuteChanged += CanExecuteChanged;
+ }
+ }
+
+ public ICommand Command
+ {
+ get => (ICommand)GetValue(CommandProperty);
+ set => SetValue(CommandProperty, value);
+ }
+
+ public static readonly StyledProperty
diff --git a/src/Avalonia/HandyControl_Avalonia/Themes/Basic/Converters.axaml b/src/Avalonia/HandyControl_Avalonia/Themes/Basic/Converters.axaml
index e5fc211cf..1b30b13fb 100644
--- a/src/Avalonia/HandyControl_Avalonia/Themes/Basic/Converters.axaml
+++ b/src/Avalonia/HandyControl_Avalonia/Themes/Basic/Converters.axaml
@@ -17,5 +17,6 @@
+
diff --git a/src/Avalonia/HandyControl_Avalonia/Themes/Styles/AutoCompleteBox.axaml b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/AutoCompleteBox.axaml
index acc05f8c4..dfdfcfc86 100644
--- a/src/Avalonia/HandyControl_Avalonia/Themes/Styles/AutoCompleteBox.axaml
+++ b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/AutoCompleteBox.axaml
@@ -1,4 +1,4 @@
-
-
+
-
+
-
+
+
@@ -57,6 +58,8 @@
+
+
diff --git a/src/Avalonia/HandyControl_Avalonia/Themes/Styles/MessageBox.axaml b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/MessageBox.axaml
new file mode 100644
index 000000000..50f6df4ab
--- /dev/null
+++ b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/MessageBox.axaml
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia/HandyControl_Avalonia/Themes/Styles/NumericUpDown.axaml b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/NumericUpDown.axaml
index 63a5d4952..4b4bcdb9a 100644
--- a/src/Avalonia/HandyControl_Avalonia/Themes/Styles/NumericUpDown.axaml
+++ b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/NumericUpDown.axaml
@@ -1,4 +1,4 @@
-
-
+
@@ -11,7 +11,7 @@
-
+
-
+
@@ -248,9 +248,9 @@
+ Value="{Binding $parent[ProgressBar].Bounds.Width, Converter={StaticResource DoubleExpandConverter}, ConverterParameter=40}" />
+ Value="{Binding $parent[ProgressBar].Bounds.Height}" />
@@ -282,9 +282,9 @@
+ Value="{Binding $parent[ProgressBar].Bounds.Width}" />
+ Value="{Binding $parent[ProgressBar].Bounds.Height, Converter={StaticResource DoubleExpandConverter}, ConverterParameter=40}" />
diff --git a/src/Avalonia/HandyControl_Avalonia/Themes/Styles/SearchBar.axaml b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/SearchBar.axaml
new file mode 100644
index 000000000..fd78a16a8
--- /dev/null
+++ b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/SearchBar.axaml
@@ -0,0 +1,603 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia/HandyControl_Avalonia/Themes/Styles/TextBox.axaml b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/TextBox.axaml
index 5bc5a285e..76c55212d 100644
--- a/src/Avalonia/HandyControl_Avalonia/Themes/Styles/TextBox.axaml
+++ b/src/Avalonia/HandyControl_Avalonia/Themes/Styles/TextBox.axaml
@@ -1,4 +1,4 @@
-
-
+
-
-
-
values, Type targetType, object? parameter, CultureInfo culture)
+ {
+ return values?.All(x => x is bool && (bool)x == true) == true;
+ }
+}