diff --git a/src/ARKServerManager/ARKServerManager.csproj b/src/ARKServerManager/ARKServerManager.csproj
index d17c1431..ad86fc83 100644
--- a/src/ARKServerManager/ARKServerManager.csproj
+++ b/src/ARKServerManager/ARKServerManager.csproj
@@ -264,6 +264,9 @@
DataDirectoryWindow.xaml
+
+ FindSettingWindow.xaml
+
PlayerListWindow.xaml
@@ -458,6 +461,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/src/ARKServerManager/Globalization/en-US/en-US.xaml b/src/ARKServerManager/Globalization/en-US/en-US.xaml
index 17dfe7f8..c41346d9 100644
--- a/src/ARKServerManager/Globalization/en-US/en-US.xaml
+++ b/src/ARKServerManager/Globalization/en-US/en-US.xaml
@@ -993,6 +993,8 @@
+ Find
+ Find Setting
Create Support Zip
Create a zip file that contains all the files necessary for use by the server manager support team to diagnose a problem.
Sync
@@ -5741,5 +5743,13 @@
Count:
Map:
+
+
+ Find Settings
+
+ The setting was not found: {0}
+
+ Find
+
\ No newline at end of file
diff --git a/src/ARKServerManager/Styles/Default.xaml b/src/ARKServerManager/Styles/Default.xaml
index 761bb608..23d2a652 100644
--- a/src/ARKServerManager/Styles/Default.xaml
+++ b/src/ARKServerManager/Styles/Default.xaml
@@ -576,6 +576,12 @@
+
+
+
+
+
+
diff --git a/src/ARKServerManager/UserControls/ServerSettingsControl.xaml b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml
index 3dac235a..9a3055e6 100644
--- a/src/ARKServerManager/UserControls/ServerSettingsControl.xaml
+++ b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml
@@ -210,16 +210,18 @@
+
-
-
+
+
+
-
+
@@ -239,10 +241,10 @@
-
-
+
+
-
+
@@ -303,7 +305,7 @@
-
@@ -1572,15 +1574,15 @@
-
+
-
-
-
+
+
+
-
-
-
+
+
+
@@ -1783,33 +1785,33 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
@@ -1817,7 +1819,7 @@
-
+
@@ -1830,7 +1832,7 @@
-
+
@@ -1844,10 +1846,10 @@
-
-
-
-
+
+
+
+
@@ -1868,9 +1870,9 @@
-
-
-
+
+
+
@@ -1897,23 +1899,23 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -1925,7 +1927,7 @@
-
+
@@ -1936,7 +1938,7 @@
-
+
@@ -1946,7 +1948,7 @@
-
+
@@ -1996,7 +1998,7 @@
-
+
@@ -2008,14 +2010,14 @@
-
-
+
+
-
+
@@ -2026,7 +2028,7 @@
-
+
@@ -2036,13 +2038,13 @@
-
+
-
+
@@ -2069,7 +2071,7 @@
-
+
@@ -2096,8 +2098,8 @@
-
-
+
+
@@ -2114,9 +2116,9 @@
-
-
-
+
+
+
@@ -2136,8 +2138,8 @@
-
-
+
+
@@ -2156,7 +2158,10 @@
-
+
@@ -2229,11 +2234,11 @@
-
-
+
+
-
-
+
+
@@ -2277,16 +2282,16 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
@@ -2318,7 +2323,7 @@
-
+
@@ -2333,7 +2338,7 @@
-
+
@@ -2368,7 +2373,7 @@
-
+
@@ -2446,7 +2451,7 @@
-
+
@@ -2455,7 +2460,7 @@
-
+
@@ -2476,17 +2481,17 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
@@ -2502,17 +2507,17 @@
-
-
+
+
-
+
-
+
@@ -2520,11 +2525,11 @@
-
-
-
-
-
+
+
+
+
+
@@ -2867,7 +2872,7 @@
-
+
@@ -2901,7 +2906,7 @@
-
+
@@ -2935,7 +2940,7 @@
-
+
@@ -2969,7 +2974,7 @@
-
+
@@ -3003,7 +3008,7 @@
-
+
@@ -3037,7 +3042,7 @@
-
+
@@ -3089,8 +3094,8 @@
-
-
+
+
@@ -3137,15 +3142,15 @@
-
+
-
+
-
+
@@ -3266,9 +3271,9 @@
-
+
-
+
@@ -3322,26 +3327,26 @@
-
+
-
+
-
-
-
+
+
+
-
+
@@ -3350,17 +3355,17 @@
-
+
-
-
-
-
+
+
+
+
-
+
@@ -3368,13 +3373,13 @@
-
-
+
+
-
+
-
+
@@ -3389,13 +3394,13 @@
-
+
-
+
@@ -3408,7 +3413,7 @@
-
+
@@ -3449,12 +3454,12 @@
-
+
-
+
@@ -3482,7 +3487,7 @@
-
+
@@ -3522,9 +3527,9 @@
-
-
-
-
-
+
+
@@ -4004,7 +4009,7 @@
-
+
@@ -4628,8 +4633,8 @@
-
-
+
+
@@ -6139,7 +6144,7 @@
-
+
@@ -6428,7 +6433,7 @@
-
+
@@ -6457,15 +6462,15 @@
-
-
+
+
-
-
+
+
-
-
-
+
+
+
diff --git a/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs
index 8127bbcc..848d0ade 100644
--- a/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs
+++ b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs
@@ -1,4 +1,16 @@
-using System;
+using Microsoft.WindowsAPICodePack.Dialogs;
+using ServerManagerTool.Common;
+using ServerManagerTool.Common.Controls;
+using ServerManagerTool.Common.Lib;
+using ServerManagerTool.Common.Model;
+using ServerManagerTool.Common.Serialization;
+using ServerManagerTool.Common.Utils;
+using ServerManagerTool.Enums;
+using ServerManagerTool.Lib;
+using ServerManagerTool.Lib.ViewModel;
+using ServerManagerTool.Plugin.Common;
+using ServerManagerTool.Utils;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
@@ -13,17 +25,7 @@ using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
-using Microsoft.WindowsAPICodePack.Dialogs;
-using ServerManagerTool.Common;
-using ServerManagerTool.Common.Lib;
-using ServerManagerTool.Common.Model;
-using ServerManagerTool.Common.Serialization;
-using ServerManagerTool.Common.Utils;
-using ServerManagerTool.Enums;
-using ServerManagerTool.Lib;
-using ServerManagerTool.Lib.ViewModel;
-using ServerManagerTool.Plugin.Common;
-using ServerManagerTool.Utils;
+using System.Windows.Media;
using WPFSharp.Globalizer;
namespace ServerManagerTool
@@ -32,6 +34,8 @@ namespace ServerManagerTool
{
private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
private CancellationTokenSource _upgradeCancellationSource = null;
+ private FindSettingWindow _findSettingWindow = null;
+ private Control _lastFoundControl = null;
// Using a DependencyProperty as the backing store for ServerManager. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BaseDinoModListProperty = DependencyProperty.Register(nameof(BaseDinoModList), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null));
@@ -427,6 +431,12 @@ namespace ServerManagerTool
RefreshBaseGameMapsList();
RefreshBaseTotalConversionsList();
}
+
+ if (sender is FindSettingWindow)
+ {
+ _findSettingWindow = null;
+ UnselectControl();
+ }
}
private void ModDetailsWindow_SavePerformed(object sender, ProfileEventArgs e)
@@ -1149,6 +1159,18 @@ namespace ServerManagerTool
window.ShowDialog();
}
+ private void SettingFind_Click(object sender, RoutedEventArgs e)
+ {
+ if (_findSettingWindow is null)
+ {
+ _findSettingWindow = new FindSettingWindow(this);
+ _findSettingWindow.Owner = Window.GetWindow(this);
+ _findSettingWindow.Closed += Window_Closed;
+ }
+ _findSettingWindow.Show();
+ _findSettingWindow.Focus();
+ }
+
private void HiddenField_GotFocus(object sender, RoutedEventArgs e)
{
var hideTextBox = sender as TextBox;
@@ -1282,7 +1304,7 @@ namespace ServerManagerTool
private void EnableSOTFCheckbox_SourceUpdated(object sender, DataTransferEventArgs e)
{
- var checkBox = sender as CheckBox;
+ var checkBox = sender as CheckBoxAndTextBlock;
if (checkBox == null || checkBox != EnableSOTFCheckbox)
return;
@@ -4333,6 +4355,65 @@ namespace ServerManagerTool
}
}
+ public void SelectControl(Control control)
+ {
+ if (control is null)
+ return;
+
+ bool focused = false;
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ Window.GetWindow(this)?.Activate();
+
+ UnselectControl();
+
+ var parent = WindowUtils.TryFindParent(control);
+ if (parent != null)
+ {
+ parent.IsExpanded = true;
+ }
+
+ control.Background = Brushes.AliceBlue;
+ control.BringIntoView();
+
+ if (control is AnnotatedSlider)
+ {
+ focused = ((AnnotatedSlider)control).Focus();
+ }
+ else if (control is AnnotatedCheckBoxAndFloatSlider)
+ {
+ focused = ((AnnotatedCheckBoxAndFloatSlider)control).Focus();
+ }
+ else if (control is AnnotatedCheckBoxAndIntegerSlider)
+ {
+ focused = ((AnnotatedCheckBoxAndIntegerSlider)control).Focus();
+ }
+ else if (control is AnnotatedCheckBoxAndLongSlider)
+ {
+ focused = ((AnnotatedCheckBoxAndLongSlider)control).Focus();
+ }
+ else if (control is CheckBoxAndTextBlock)
+ {
+ focused = ((CheckBoxAndTextBlock)control).Focus();
+ }
+ else
+ {
+ focused = control.Focus();
+ }
+
+ _lastFoundControl = control;
+ });
+ }
+
+ public void UnselectControl()
+ {
+ if (_lastFoundControl is null)
+ return;
+
+ _lastFoundControl.Background = null;
+ _lastFoundControl = null;
+ }
+
private async Task UpdateServer(bool establishLock, bool updateServer, bool updateMods, bool closeProgressWindow)
{
if (_upgradeCancellationSource != null)
diff --git a/src/ARKServerManager/VersionFeed.xml b/src/ARKServerManager/VersionFeed.xml
index 0bec593b..67e92efc 100644
--- a/src/ARKServerManager/VersionFeed.xml
+++ b/src/ARKServerManager/VersionFeed.xml
@@ -5,17 +5,22 @@
Ark Server Manager Version Feed
This is the Ark Server Manager release version feed.
- 2022-06-17T00:00:00Z
+ 2022-06-18T00:00:00Z
urn:uuid:1AE0925B-64EB-4177-B834-7A75FA46E807
- 1.1.433 (1.1.433.2)
- 1.1.433.2
+ 1.1.433 (1.1.433.3)
+ 1.1.433.3
- 2022-06-17T00:00:00Z
+ 2022-06-18T00:00:00Z
+ NEW
+
+
+ - Server Settings - added new find button to find settings by name.
+
CHANGE
diff --git a/src/ARKServerManager/VersionFeedBeta.xml b/src/ARKServerManager/VersionFeedBeta.xml
index 038af8e9..18c22ab4 100644
--- a/src/ARKServerManager/VersionFeedBeta.xml
+++ b/src/ARKServerManager/VersionFeedBeta.xml
@@ -5,7 +5,30 @@
Ark Server Manager Version Feed
This is the Ark Server Manager beta version feed.
- 2022-06-17T00:00:00Z
+ 2022-06-18T00:00:00Z
+
+
+ urn:uuid:1AE0925B-64EB-4177-B834-7A75FA46E807
+ 1.1.433 (1.1.433.3)
+ 1.1.433.3
+
+ 2022-06-18T00:00:00Z
+
+
+
+ NEW
+
+
+ - Server Settings - added new find button to find settings by name.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
urn:uuid:1AE0925B-64EB-4177-B834-7A75FA46E807
diff --git a/src/ARKServerManager/Windows/FindSettingWindow.xaml b/src/ARKServerManager/Windows/FindSettingWindow.xaml
new file mode 100644
index 00000000..a98a9c09
--- /dev/null
+++ b/src/ARKServerManager/Windows/FindSettingWindow.xaml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ARKServerManager/Windows/FindSettingWindow.xaml.cs b/src/ARKServerManager/Windows/FindSettingWindow.xaml.cs
new file mode 100644
index 00000000..3c15f1e1
--- /dev/null
+++ b/src/ARKServerManager/Windows/FindSettingWindow.xaml.cs
@@ -0,0 +1,164 @@
+using ServerManagerTool.Common.Attibutes;
+using ServerManagerTool.Common.Extensions;
+using ServerManagerTool.Common.Utils;
+using ServerManagerTool.Lib;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using WPFSharp.Globalizer;
+
+namespace ServerManagerTool
+{
+ ///
+ /// Interaction logic for FindSettingWindow.xaml
+ ///
+ public partial class FindSettingWindow : Window
+ {
+ private static List<(string setting, string profileProperty)> _profileSettings = null;
+ private static List<(string setting, Control control)> _settingControls = null;
+
+ private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
+ private int _controlIndex = -1;
+ private ServerSettingsControl _serverSettingsControl;
+
+ public static readonly DependencyProperty FindSettingStringProperty = DependencyProperty.Register(nameof(FindSettingString), typeof(string), typeof(FindSettingWindow), new PropertyMetadata(""));
+
+ public FindSettingWindow(ServerSettingsControl control)
+ {
+ InitializeComponent();
+ WindowUtils.RemoveDefaultResourceDictionary(this, Config.Default.DefaultGlobalizationFile);
+
+ _serverSettingsControl = control;
+
+ LoadSettings(control.Settings);
+ LoadControls(control);
+
+ this.DataContext = this;
+ }
+
+ public string FindSettingString
+ {
+ get { return (string)GetValue(FindSettingStringProperty); }
+ set { SetValue(FindSettingStringProperty, value); }
+ }
+
+ private async void Find_Click(object sender, RoutedEventArgs e)
+ {
+ if (string.IsNullOrWhiteSpace(FindSettingString))
+ return;
+
+ var cursor = this.Cursor;
+
+ try
+ {
+ Application.Current.Dispatcher.Invoke(() => this.Cursor = Cursors.Wait);
+ await Task.Delay(100);
+
+ _serverSettingsControl.UnselectControl();
+
+ var foundControls = _settingControls
+ .Where(s => s.setting.Contains(FindSettingString, StringComparison.OrdinalIgnoreCase))
+ .Select(s => s.control)
+ .ToArray();
+ if (foundControls.Length == 0)
+ {
+ MessageBox.Show(string.Format(_globalizer.GetResourceString("FindSettingWindow_NotFoundErrorLabel"), FindSettingString), _globalizer.GetResourceString("FindSettingWindow_Title"), MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ var oldIndex = _controlIndex;
+ var newIndex = oldIndex + 1;
+ if (newIndex >= foundControls.Length)
+ {
+ _controlIndex = -1;
+ MessageBox.Show(string.Format(_globalizer.GetResourceString("FindSettingWindow_NotFoundErrorLabel"), FindSettingString), _globalizer.GetResourceString("FindSettingWindow_Title"), MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ _serverSettingsControl.SelectControl(foundControls[newIndex]);
+ _controlIndex = newIndex;
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, _globalizer.GetResourceString("FindSettingWindow_Title"), MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ finally
+ {
+ Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor);
+ }
+ }
+
+ private void LoadControls(DependencyObject parent)
+ {
+ if (_settingControls != null)
+ return;
+
+ try
+ {
+ _settingControls = WindowUtils.GetLogicalTreeControls(parent);
+ for (int i = 0; i < _settingControls.Count; i++)
+ {
+ var item = _settingControls[i];
+ var setting = _profileSettings
+ .FirstOrDefault(x => x.profileProperty.Equals(item.setting, StringComparison.OrdinalIgnoreCase))
+ .setting;
+
+ if (setting != null && !setting.Equals(item.setting, StringComparison.OrdinalIgnoreCase))
+ {
+ _settingControls[i] = (setting, item.control);
+ }
+
+#if DEBUG
+ Debug.WriteLine($"{_settingControls[i].setting}; {_settingControls[i].control.GetType().FullName}");
+#endif
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, _globalizer.GetResourceString("FindSettingWindow_Title"), MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
+ private void LoadSettings(ServerProfile profile)
+ {
+ if (_profileSettings != null)
+ return;
+
+ try
+ {
+ _profileSettings = new List<(string setting, string profileProperty)>();
+
+ var fields = profile?.GetType()
+ .GetProperties()
+ .Where(f => f.IsDefined(typeof(BaseIniFileEntryAttribute), false));
+
+ foreach (var field in fields)
+ {
+ var attributes = field
+ .GetCustomAttributes(typeof(BaseIniFileEntryAttribute), false)
+ .OfType();
+
+ foreach (var attr in attributes)
+ {
+ _profileSettings.Add((string.IsNullOrWhiteSpace(attr.Key) ? field.Name : attr.Key, field.Name));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, _globalizer.GetResourceString("FindSettingWindow_Title"), MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
+ private void FindSettingString_SourceUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
+ {
+ _serverSettingsControl.UnselectControl();
+ _controlIndex = -1;
+ }
+ }
+}
diff --git a/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndFloatSlider.xaml.cs b/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndFloatSlider.xaml.cs
index 74b31baf..74bf6092 100644
--- a/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndFloatSlider.xaml.cs
+++ b/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndFloatSlider.xaml.cs
@@ -31,6 +31,7 @@ namespace ServerManagerTool.Common.Controls
{
InitializeComponent();
+ this.Focusable = true;
Value = new NullableValue();
(this.Content as FrameworkElement).DataContext = this;
@@ -148,5 +149,13 @@ namespace ServerManagerTool.Common.Controls
}
}
}
+
+ public new bool Focus()
+ {
+ if (this.CheckBox.IsChecked ?? false == true)
+ return Slider.Focus();
+ else
+ return this.CheckBox.Focus();
+ }
}
}
diff --git a/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndIntegerSlider.xaml.cs b/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndIntegerSlider.xaml.cs
index 65e63a83..bf6a1767 100644
--- a/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndIntegerSlider.xaml.cs
+++ b/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndIntegerSlider.xaml.cs
@@ -31,6 +31,7 @@ namespace ServerManagerTool.Common.Controls
{
InitializeComponent();
+ this.Focusable = true;
Value = new NullableValue();
(this.Content as FrameworkElement).DataContext = this;
@@ -148,5 +149,13 @@ namespace ServerManagerTool.Common.Controls
}
}
}
+
+ public new bool Focus()
+ {
+ if (this.CheckBox.IsChecked ?? false == true)
+ return Slider.Focus();
+ else
+ return this.CheckBox.Focus();
+ }
}
}
diff --git a/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndLongSlider.xaml.cs b/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndLongSlider.xaml.cs
index 3f03e3a9..3027f642 100644
--- a/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndLongSlider.xaml.cs
+++ b/src/ServerManager.Common/Controls/AnnotatedCheckBoxAndLongSlider.xaml.cs
@@ -31,6 +31,7 @@ namespace ServerManagerTool.Common.Controls
{
InitializeComponent();
+ this.Focusable = true;
Value = new NullableValue();
(this.Content as FrameworkElement).DataContext = this;
@@ -148,5 +149,13 @@ namespace ServerManagerTool.Common.Controls
}
}
}
+
+ public new bool Focus()
+ {
+ if (this.CheckBox.IsChecked ?? false == true)
+ return Slider.Focus();
+ else
+ return this.CheckBox.Focus();
+ }
}
}
diff --git a/src/ServerManager.Common/Controls/AnnotatedSlider.xaml.cs b/src/ServerManager.Common/Controls/AnnotatedSlider.xaml.cs
index c72426c6..dcb4cb31 100644
--- a/src/ServerManager.Common/Controls/AnnotatedSlider.xaml.cs
+++ b/src/ServerManager.Common/Controls/AnnotatedSlider.xaml.cs
@@ -26,6 +26,15 @@ namespace ServerManagerTool.Common.Controls
public static readonly DependencyProperty SuffixRelativeWidthProperty = DependencyProperty.Register(nameof(SuffixRelativeWidth), typeof(string), typeof(AnnotatedSlider), new PropertyMetadata("1*"));
public static readonly DependencyProperty SuffixRelativeMinWidthProperty = DependencyProperty.Register(nameof(SuffixRelativeMinWidth), typeof(string), typeof(AnnotatedSlider), new PropertyMetadata("0"));
+ public AnnotatedSlider()
+ {
+ InitializeComponent();
+
+ this.Focusable = true;
+
+ (this.Content as FrameworkElement).DataContext = this;
+ }
+
public string Label
{
get { return (string)GetValue(LabelProperty); }
@@ -128,12 +137,6 @@ namespace ServerManagerTool.Common.Controls
set { SetValue(SuffixRelativeMinWidthProperty, value); }
}
- public AnnotatedSlider()
- {
- InitializeComponent();
- (this.Content as FrameworkElement).DataContext = this;
- }
-
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
{
if(Slider.IsFocused)
@@ -144,5 +147,10 @@ namespace ServerManagerTool.Common.Controls
}
}
}
+
+ public new bool Focus()
+ {
+ return Slider.Focus();
+ }
}
}
diff --git a/src/ServerManager.Common/Controls/CheckBoxAndTextBlock.xaml b/src/ServerManager.Common/Controls/CheckBoxAndTextBlock.xaml
new file mode 100644
index 00000000..c38ef416
--- /dev/null
+++ b/src/ServerManager.Common/Controls/CheckBoxAndTextBlock.xaml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ServerManager.Common/Controls/CheckBoxAndTextBlock.xaml.cs b/src/ServerManager.Common/Controls/CheckBoxAndTextBlock.xaml.cs
new file mode 100644
index 00000000..4d9322f2
--- /dev/null
+++ b/src/ServerManager.Common/Controls/CheckBoxAndTextBlock.xaml.cs
@@ -0,0 +1,48 @@
+using System.Windows;
+using System.Windows.Controls;
+
+namespace ServerManagerTool.Common.Controls
+{
+ ///
+ /// Interaction logic for CheckBoxAndTextBlock.xaml
+ ///
+ public partial class CheckBoxAndTextBlock : UserControl
+ {
+ public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register(nameof(IsChecked), typeof(bool), typeof(CheckBoxAndTextBlock));
+ public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(CheckBoxAndTextBlock));
+
+ public CheckBoxAndTextBlock()
+ {
+ InitializeComponent();
+
+ this.Focusable = true;
+
+ (this.Content as FrameworkElement).DataContext = this;
+ }
+
+ public bool IsChecked
+ {
+ get { return (bool)GetValue(IsCheckedProperty); }
+ set { SetValue(IsCheckedProperty, value); }
+ }
+
+ public string Text
+ {
+ get { return (string)GetValue(TextProperty); }
+ set { SetValue(TextProperty, value); }
+ }
+
+ public new bool Focus()
+ {
+ return CheckBox.Focus();
+ }
+
+ private void Label_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ if (this.IsEnabled && this.CheckBox.IsEnabled)
+ {
+ this.IsChecked = !this.IsChecked;
+ }
+ }
+ }
+}
diff --git a/src/ServerManager.Common/Extensions/StringExtensions.cs b/src/ServerManager.Common/Extensions/StringExtensions.cs
new file mode 100644
index 00000000..d136b455
--- /dev/null
+++ b/src/ServerManager.Common/Extensions/StringExtensions.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace ServerManagerTool.Common.Extensions
+{
+ public static class StringExtensions
+ {
+ public static bool Contains(this string value, string substring, StringComparison comparisonType)
+ {
+ if (substring == null)
+ throw new ArgumentNullException(nameof(substring), $"{nameof(substring)} cannot be null.");
+ if (!Enum.IsDefined(typeof(StringComparison), comparisonType))
+ throw new ArgumentException($"{nameof(comparisonType)} is not a member of StringComparison", nameof(comparisonType));
+
+ return value.IndexOf(substring, comparisonType) >= 0;
+ }
+ }
+}
diff --git a/src/ServerManager.Common/ServerManager.Common.csproj b/src/ServerManager.Common/ServerManager.Common.csproj
index 673640ab..8718d55b 100644
--- a/src/ServerManager.Common/ServerManager.Common.csproj
+++ b/src/ServerManager.Common/ServerManager.Common.csproj
@@ -13,6 +13,7 @@
+
@@ -30,6 +31,10 @@
+
+ Designer
+ MSBuild:Compile
+
diff --git a/src/ServerManager.Common/Utils/WindowUtils.cs b/src/ServerManager.Common/Utils/WindowUtils.cs
index 480435cc..89fc1541 100644
--- a/src/ServerManager.Common/Utils/WindowUtils.cs
+++ b/src/ServerManager.Common/Utils/WindowUtils.cs
@@ -1,4 +1,7 @@
-using System.Linq;
+using ServerManagerTool.Common.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
@@ -66,10 +69,11 @@ namespace ServerManagerTool.Common.Utils
{
if (child == null) return null;
var contentElement = child as ContentElement;
+ DependencyObject parent = null;
if (contentElement != null)
{
- var parent = ContentOperations.GetParent(contentElement);
+ parent = ContentOperations.GetParent(contentElement);
if (parent != null) return parent;
var fce = contentElement as FrameworkContentElement;
@@ -77,7 +81,10 @@ namespace ServerManagerTool.Common.Utils
}
//if it's not a ContentElement, rely on VisualTreeHelper
- return VisualTreeHelper.GetParent(child);
+ parent = VisualTreeHelper.GetParent(child);
+ if (parent is null)
+ parent = LogicalTreeHelper.GetParent(child);
+ return parent;
}
///
@@ -118,5 +125,48 @@ namespace ServerManagerTool.Common.Utils
if (element is T) return (T)element;
return TryFindParent(element);
}
+
+ private static Dictionary BindingProperties = new Dictionary
+ {
+ { "System.Windows.Controls.CheckBox", CheckBox.IsCheckedProperty },
+ { "System.Windows.Controls.ComboBox", ComboBox.ItemsSourceProperty },
+ { "System.Windows.Controls.TextBox", TextBox.TextProperty },
+ { "System.Windows.Controls.Slider", Slider.ValueProperty },
+ { "System.Windows.Controls.DataGrid", DataGrid.ItemsSourceProperty },
+ { "ServerManagerTool.Common.Controls.AnnotatedSlider", AnnotatedSlider.ValueProperty },
+ { "ServerManagerTool.Common.Controls.AnnotatedCheckBoxAndFloatSlider", AnnotatedCheckBoxAndFloatSlider.ValueProperty },
+ { "ServerManagerTool.Common.Controls.AnnotatedCheckBoxAndIntegerSlider", AnnotatedCheckBoxAndIntegerSlider.ValueProperty },
+ { "ServerManagerTool.Common.Controls.AnnotatedCheckBoxAndLongSlider", AnnotatedCheckBoxAndLongSlider.ValueProperty },
+ { "ServerManagerTool.Common.Controls.CheckBoxAndTextBlock", CheckBoxAndTextBlock.IsCheckedProperty },
+ };
+
+ public static List<(string setting, Control control)> GetLogicalTreeControls(DependencyObject parent)
+ {
+ var results = new List<(string setting, Control control)>();
+
+ var children = LogicalTreeHelper.GetChildren(parent).OfType();
+ foreach (var child in children)
+ {
+ var recurse = true;
+ if (child is Visual childControl)
+ {
+ var bindingProperty = BindingProperties.FirstOrDefault(b => b.Key.Equals(childControl.GetType().FullName)).Value;
+ if (bindingProperty != null)
+ {
+ var binding = BindingOperations.GetBinding(childControl, bindingProperty);
+ if (binding != null)
+ {
+ results.Add((binding.Path.Path, child as Control));
+ recurse = false;
+ }
+ }
+ }
+
+ if (recurse)
+ results.AddRange(GetLogicalTreeControls(child));
+ }
+
+ return results;
+ }
}
}