diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PropertyGridDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PropertyGridDemoCtl.xaml
index 37108e68..eff6b153 100644
--- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PropertyGridDemoCtl.xaml
+++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PropertyGridDemoCtl.xaml
@@ -1,7 +1,23 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/DatePropertyEditor.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/DatePropertyEditor.cs
new file mode 100644
index 00000000..6ca651c2
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/DatePropertyEditor.cs
@@ -0,0 +1,19 @@
+using System.Windows;
+
+namespace HandyControl.Controls
+{
+ public class DatePropertyEditor : PropertyEditorBase
+ {
+ public override FrameworkElement CreateElement(PropertyItem propertyItem)
+ {
+ var picker = new DateTimePicker
+ {
+ IsEnabled = !propertyItem.IsReadOnly
+ };
+
+ picker.SetBinding(System.Windows.Controls.DatePicker.SelectedDateProperty, CreateBinding(propertyItem));
+
+ return picker;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/IntegerPropertyEditor.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/IntegerPropertyEditor.cs
index 849f62e1..bd48007b 100644
--- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/IntegerPropertyEditor.cs
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/IntegerPropertyEditor.cs
@@ -2,9 +2,9 @@
namespace HandyControl.Controls
{
- public class IntegerPropertyEditor : PropertyEditorBase
+ public class NumberPropertyEditor : PropertyEditorBase
{
- public IntegerPropertyEditor(double minimum, double maximum)
+ public NumberPropertyEditor(double minimum, double maximum)
{
Minimum = minimum;
Maximum = maximum;
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/NumberPropertyEditor.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/NumberPropertyEditor.cs
new file mode 100644
index 00000000..305bcd9f
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/NumberPropertyEditor.cs
@@ -0,0 +1,36 @@
+using System.Windows;
+
+namespace HandyControl.Controls
+{
+ public class NumberPropertyEditor : PropertyEditorBase
+ {
+ public NumberPropertyEditor()
+ {
+
+ }
+
+ public NumberPropertyEditor(double minimum, double maximum)
+ {
+ Minimum = minimum;
+ Maximum = maximum;
+ }
+
+ public double Minimum { get; set; }
+
+ public double Maximum { get; set; }
+
+ public override FrameworkElement CreateElement(PropertyItem propertyItem)
+ {
+ var numericUpDown = new NumericUpDown
+ {
+ IsReadOnly = propertyItem.IsReadOnly,
+ Minimum = Minimum,
+ Maximum = Maximum
+ };
+
+ numericUpDown.SetBinding(NumericUpDown.ValueProperty, CreateBinding(propertyItem));
+
+ return numericUpDown;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PlainTextPropertyEditor.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PlainTextPropertyEditor.cs
new file mode 100644
index 00000000..77663d9b
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PlainTextPropertyEditor.cs
@@ -0,0 +1,19 @@
+using System.Windows;
+
+namespace HandyControl.Controls
+{
+ public class PlainTextPropertyEditor : PropertyEditorBase
+ {
+ public override FrameworkElement CreateElement(PropertyItem propertyItem)
+ {
+ var textbox = new System.Windows.Controls.TextBox
+ {
+ IsReadOnly = propertyItem.IsReadOnly
+ };
+
+ textbox.SetBinding(System.Windows.Controls.TextBox.TextProperty, CreateBinding(propertyItem));
+
+ return textbox;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PropertyEditorBase.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PropertyEditorBase.cs
index 927779a0..bda2df14 100644
--- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PropertyEditorBase.cs
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PropertyEditorBase.cs
@@ -11,8 +11,12 @@ namespace HandyControl.Controls
new Binding(propertyItem.PropertyName)
{
Source = propertyItem.Value,
- Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay,
- UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
+ Mode = GetBindingMode(),
+ UpdateSourceTrigger = GetUpdateSourceTrigger()
};
+
+ public virtual BindingMode GetBindingMode() => BindingMode.OneWay;
+
+ public virtual UpdateSourceTrigger GetUpdateSourceTrigger() => UpdateSourceTrigger.Default;
}
}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/StringPropertyEditor.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/StringPropertyEditor.cs
index cdd5ef28..77663d9b 100644
--- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/StringPropertyEditor.cs
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/StringPropertyEditor.cs
@@ -2,7 +2,7 @@
namespace HandyControl.Controls
{
- public class StringPropertyEditor : PropertyEditorBase
+ public class PlainTextPropertyEditor : PropertyEditorBase
{
public override FrameworkElement CreateElement(PropertyItem propertyItem)
{
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/BooleanPropertyEditor.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/SwitchPropertyEditor.cs
similarity index 91%
rename from src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/BooleanPropertyEditor.cs
rename to src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/SwitchPropertyEditor.cs
index 4601d51c..706646be 100644
--- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/BooleanPropertyEditor.cs
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/SwitchPropertyEditor.cs
@@ -4,7 +4,7 @@ using HandyControl.Tools;
namespace HandyControl.Controls
{
- public class BooleanPropertyEditor : PropertyEditorBase
+ public class SwitchPropertyEditor : PropertyEditorBase
{
public override FrameworkElement CreateElement(PropertyItem propertyItem)
{
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/TimePropertyEditor.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/TimePropertyEditor.cs
new file mode 100644
index 00000000..d39ca9c4
--- /dev/null
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/TimePropertyEditor.cs
@@ -0,0 +1,19 @@
+using System.Windows;
+
+namespace HandyControl.Controls
+{
+ public class TimePropertyEditor : PropertyEditorBase
+ {
+ public override FrameworkElement CreateElement(PropertyItem propertyItem)
+ {
+ var picker = new DateTimePicker
+ {
+ IsEnabled = !propertyItem.IsReadOnly
+ };
+
+ picker.SetBinding(TimePicker.SelectedTimeProperty, CreateBinding(propertyItem));
+
+ return picker;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs
index e1b26beb..df67f1a5 100644
--- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs
@@ -1,20 +1,39 @@
-using System.Collections.Generic;
+using System;
+using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
+using System.Windows.Input;
+using HandyControl.Data;
+using HandyControl.Interactivity;
using HandyControl.Tools.Extension;
namespace HandyControl.Controls
{
[TemplatePart(Name = ElementItemsControl, Type = typeof(ItemsControl))]
+ [TemplatePart(Name = ElementSearchBar, Type = typeof(SearchBar))]
public class PropertyGrid : Control
{
private const string ElementItemsControl = "PART_ItemsControl";
+ private const string ElementSearchBar = "PART_SearchBar";
+
private ItemsControl _itemsControl;
+ private ICollectionView _dataView;
+
+ private SearchBar _searchBar;
+
+ private string _searchKey;
+
+ public PropertyGrid()
+ {
+ CommandBindings.Add(new CommandBinding(ControlCommands.SortByCategory, SortByCategory));
+ CommandBindings.Add(new CommandBinding(ControlCommands.SortByName, SortByName));
+ }
+
public virtual PropertyResolver PropertyResolver { get; } = new PropertyResolver();
public static readonly RoutedEvent SelectedObjectChangedEvent =
@@ -57,11 +76,41 @@ namespace HandyControl.Controls
set => SetValue(DescriptionProperty, value);
}
+ public static readonly DependencyProperty MaxTitleWidthProperty = DependencyProperty.Register(
+ "MaxTitleWidth", typeof(double), typeof(PropertyGrid), new PropertyMetadata(default(double)));
+
+ public double MaxTitleWidth
+ {
+ get => (double) GetValue(MaxTitleWidthProperty);
+ set => SetValue(MaxTitleWidthProperty, value);
+ }
+
+ public static readonly DependencyProperty MinTitleWidthProperty = DependencyProperty.Register(
+ "MinTitleWidth", typeof(double), typeof(PropertyGrid), new PropertyMetadata(default(double)));
+
+ public double MinTitleWidth
+ {
+ get => (double) GetValue(MinTitleWidthProperty);
+ set => SetValue(MinTitleWidthProperty, value);
+ }
+
public override void OnApplyTemplate()
{
+ if (_searchBar != null)
+ {
+ _searchBar.SearchStarted -= SearchBar_SearchStarted;
+ }
+
base.OnApplyTemplate();
_itemsControl = GetTemplateChild(ElementItemsControl) as ItemsControl;
+ _searchBar = GetTemplateChild(ElementSearchBar) as SearchBar;
+
+ if (_searchBar != null)
+ {
+ _searchBar.SearchStarted += SearchBar_SearchStarted;
+ }
+
UpdateItems(SelectedObject);
}
@@ -69,35 +118,73 @@ namespace HandyControl.Controls
{
if (obj == null || _itemsControl == null) return;
- var type = obj.GetType();
- var propertyInfos = type.GetProperties();
- var itemList = propertyInfos.Select(CreatePropertyItem).Do(item => item.InitElement()).ToList();
- _itemsControl.ItemsSource = itemList;
+ _dataView = CollectionViewSource.GetDefaultView(obj.GetType().GetProperties()
+ .Where(item => PropertyResolver.ResolveBrowsable(item)).Select(CreatePropertyItem)
+ .Do(item => item.InitElement()));
- var categorySet = new HashSet();
- foreach (var propertyItem in itemList)
- {
- categorySet.Add(propertyItem.Category);
- }
-
- var view = CollectionViewSource.GetDefaultView(itemList);
- view.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
+ SortByCategory(null, null);
+ _itemsControl.ItemsSource = _dataView;
}
- protected virtual PropertyItem CreatePropertyItem(PropertyInfo propertyInfo) =>
- new PropertyItem
+ private void SortByCategory(object sender, ExecutedRoutedEventArgs e)
+ {
+ using (_dataView.DeferRefresh())
{
- Category = PropertyResolver.ResolveCategory(propertyInfo),
- DisplayName = PropertyResolver.ResolveDisplayName(propertyInfo),
- Description = PropertyResolver.ResolveDescription(propertyInfo),
- Browsable = PropertyResolver.ResolveBrowsable(propertyInfo),
- IsReadOnly = PropertyResolver.ResolveIsReadOnly(propertyInfo),
- DefaultValue = PropertyResolver.ResolveDefaultValue(propertyInfo),
- Editor = PropertyResolver.ResolveEditor(propertyInfo),
- Converter = PropertyResolver.ResolveConverter(propertyInfo),
- Value = SelectedObject,
- PropertyName = propertyInfo.Name,
- PropertyTypeName = propertyInfo.PropertyType.FullName
- };
+ _dataView.GroupDescriptions.Clear();
+ _dataView.SortDescriptions.Clear();
+ _dataView.SortDescriptions.Add(new SortDescription(PropertyItem.CategoryProperty.Name, ListSortDirection.Ascending));
+ _dataView.SortDescriptions.Add(new SortDescription(PropertyItem.PropertyNameProperty.Name, ListSortDirection.Ascending));
+ _dataView.GroupDescriptions.Add(new PropertyGroupDescription(PropertyItem.CategoryProperty.Name));
+ }
+ }
+
+ private void SortByName(object sender, ExecutedRoutedEventArgs e)
+ {
+ using (_dataView.DeferRefresh())
+ {
+ _dataView.GroupDescriptions.Clear();
+ _dataView.SortDescriptions.Clear();
+ _dataView.SortDescriptions.Add(new SortDescription(PropertyItem.PropertyNameProperty.Name, ListSortDirection.Ascending));
+ }
+ }
+
+ private void SearchBar_SearchStarted(object sender, FunctionEventArgs e)
+ {
+ _searchKey = e.Info;
+ if (string.IsNullOrEmpty(_searchKey))
+ {
+ foreach (UIElement item in _dataView)
+ {
+ item.Show();
+ }
+ }
+ else
+ {
+ foreach (PropertyItem item in _dataView)
+ {
+ item.Show(item.PropertyName.ToLower().Contains(_searchKey) || item.DisplayName.ToLower().Contains(_searchKey));
+ }
+ }
+ }
+
+ protected virtual PropertyItem CreatePropertyItem(PropertyInfo propertyInfo) => new PropertyItem
+ {
+ Category = PropertyResolver.ResolveCategory(propertyInfo),
+ DisplayName = PropertyResolver.ResolveDisplayName(propertyInfo),
+ Description = PropertyResolver.ResolveDescription(propertyInfo),
+ IsReadOnly = PropertyResolver.ResolveIsReadOnly(propertyInfo),
+ DefaultValue = PropertyResolver.ResolveDefaultValue(propertyInfo),
+ Editor = PropertyResolver.ResolveEditor(propertyInfo),
+ Converter = PropertyResolver.ResolveConverter(propertyInfo),
+ Value = SelectedObject,
+ PropertyName = propertyInfo.Name,
+ PropertyTypeName = propertyInfo.PropertyType.FullName
+ };
+
+ protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
+ {
+ base.OnRenderSizeChanged(sizeInfo);
+ TitleElement.SetTitleWidth(this, new GridLength(Math.Max(MinTitleWidth, Math.Min(MaxTitleWidth, ActualWidth / 3))));
+ }
}
}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyItem.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyItem.cs
index 6b4f8c71..77d2075d 100644
--- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyItem.cs
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyItem.cs
@@ -51,15 +51,6 @@ namespace HandyControl.Controls
set => SetValue(DescriptionProperty, value);
}
- public static readonly DependencyProperty BrowsableProperty = DependencyProperty.Register(
- "Browsable", typeof(bool), typeof(PropertyItem), new PropertyMetadata(default(bool)));
-
- public bool Browsable
- {
- get => (bool)GetValue(BrowsableProperty);
- set => SetValue(BrowsableProperty, value);
- }
-
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register(
"IsReadOnly", typeof(bool), typeof(PropertyItem), new PropertyMetadata(default(bool)));
diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyResolver.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyResolver.cs
index 8fc8c230..baceed87 100644
--- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyResolver.cs
+++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyResolver.cs
@@ -25,7 +25,8 @@ namespace HandyControl.Controls
[typeof(ulong)] = EditorTypeCode.UInt64Number,
[typeof(float)] = EditorTypeCode.SingleNumber,
[typeof(double)] = EditorTypeCode.DoubleNumber,
- [typeof(bool)] = EditorTypeCode.Switch
+ [typeof(bool)] = EditorTypeCode.Switch,
+ [typeof(DateTime)] = EditorTypeCode.DateTime
};
public string ResolveCategory(PropertyInfo propertyInfo)
@@ -121,24 +122,24 @@ namespace HandyControl.Controls
TypeCodeDic.TryGetValue(type, out var editorType)
? (PropertyEditorBase) (editorType switch
{
- EditorTypeCode.PlainText => new StringPropertyEditor(),
- EditorTypeCode.SByteNumber => new IntegerPropertyEditor(sbyte.MinValue, sbyte.MaxValue),
- EditorTypeCode.ByteNumber => new IntegerPropertyEditor(byte.MinValue, byte.MaxValue),
- EditorTypeCode.Int16Number => new IntegerPropertyEditor(short.MinValue, short.MaxValue),
- EditorTypeCode.UInt16Number => new IntegerPropertyEditor(ushort.MinValue, ushort.MaxValue),
- EditorTypeCode.Int32Number => new IntegerPropertyEditor(int.MinValue, int.MaxValue),
- EditorTypeCode.UInt32Number => new IntegerPropertyEditor(uint.MinValue, uint.MaxValue),
- EditorTypeCode.Int64Number => new IntegerPropertyEditor(long.MinValue, long.MaxValue),
- EditorTypeCode.UInt64Number => new IntegerPropertyEditor(ulong.MinValue, ulong.MaxValue),
- EditorTypeCode.SingleNumber => new IntegerPropertyEditor(float.MinValue, float.MaxValue),
- EditorTypeCode.DoubleNumber => new IntegerPropertyEditor(double.MinValue, double.MaxValue),
- EditorTypeCode.Switch => new BooleanPropertyEditor(),
+ EditorTypeCode.PlainText => new PlainTextPropertyEditor(),
+ EditorTypeCode.SByteNumber => new NumberPropertyEditor(sbyte.MinValue, sbyte.MaxValue),
+ EditorTypeCode.ByteNumber => new NumberPropertyEditor(byte.MinValue, byte.MaxValue),
+ EditorTypeCode.Int16Number => new NumberPropertyEditor(short.MinValue, short.MaxValue),
+ EditorTypeCode.UInt16Number => new NumberPropertyEditor(ushort.MinValue, ushort.MaxValue),
+ EditorTypeCode.Int32Number => new NumberPropertyEditor(int.MinValue, int.MaxValue),
+ EditorTypeCode.UInt32Number => new NumberPropertyEditor(uint.MinValue, uint.MaxValue),
+ EditorTypeCode.Int64Number => new NumberPropertyEditor(long.MinValue, long.MaxValue),
+ EditorTypeCode.UInt64Number => new NumberPropertyEditor(ulong.MinValue, ulong.MaxValue),
+ EditorTypeCode.SingleNumber => new NumberPropertyEditor(float.MinValue, float.MaxValue),
+ EditorTypeCode.DoubleNumber => new NumberPropertyEditor(double.MinValue, double.MaxValue),
+ EditorTypeCode.Switch => new SwitchPropertyEditor(),
EditorTypeCode.DateTime => new DateTimePropertyEditor(),
- _ => new StringPropertyEditor()
+ _ => new PlainTextPropertyEditor()
})
- : new StringPropertyEditor();
+ : new PlainTextPropertyEditor();
- public virtual PropertyEditorBase CreateEditor(Type type) => new StringPropertyEditor();
+ public virtual PropertyEditorBase CreateEditor(Type type) => new PlainTextPropertyEditor();
private enum EditorTypeCode
{
diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems
index 4e9427f6..d4698ad5 100644
--- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems
+++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems
@@ -40,11 +40,13 @@
-
+
+
+
-
-
+
+
@@ -429,6 +431,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/src/Shared/HandyControl_Shared/Interactivity/Commands/ControlCommands.cs b/src/Shared/HandyControl_Shared/Interactivity/Commands/ControlCommands.cs
index 6e31c2b2..fdcf231b 100644
--- a/src/Shared/HandyControl_Shared/Interactivity/Commands/ControlCommands.cs
+++ b/src/Shared/HandyControl_Shared/Interactivity/Commands/ControlCommands.cs
@@ -171,5 +171,15 @@ namespace HandyControl.Interactivity
/// 开始截图
///
public static StartScreenshotCommand StartScreenshot { get; } = new StartScreenshotCommand();
+
+ ///
+ /// 按照类别排序
+ ///
+ public static RoutedCommand SortByCategory { get; } = new RoutedCommand(nameof(SortByCategory), typeof(ControlCommands));
+
+ ///
+ /// 按照名称排序
+ ///
+ public static RoutedCommand SortByName { get; } = new RoutedCommand(nameof(SortByName), typeof(ControlCommands));
}
}
\ No newline at end of file
diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/Base/PropertyGridBaseStyle.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/Base/PropertyGridBaseStyle.xaml
index b0b8b236..bbe21694 100644
--- a/src/Shared/HandyControl_Shared/Themes/Styles/Base/PropertyGridBaseStyle.xaml
+++ b/src/Shared/HandyControl_Shared/Themes/Styles/Base/PropertyGridBaseStyle.xaml
@@ -2,10 +2,14 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:o="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:hc="clr-namespace:HandyControl.Controls"
- xmlns:themes="clr-namespace:HandyControl.Themes">
+ xmlns:themes="clr-namespace:HandyControl.Themes"
+ xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
+
+
+
@@ -20,7 +24,7 @@
-
+
@@ -34,10 +38,11 @@
+
+
+
+
+
+