diff --git a/Hawkeye.VisionBuilder.UI.Sources.Emulation/EmulationSettings.cs b/Hawkeye.VisionBuilder.UI.Sources.Emulation/EmulationSettings.cs
index 17622e3..f25c55c 100644
--- a/Hawkeye.VisionBuilder.UI.Sources.Emulation/EmulationSettings.cs
+++ b/Hawkeye.VisionBuilder.UI.Sources.Emulation/EmulationSettings.cs
@@ -19,9 +19,9 @@ public class EmulationSettings : ISettings
public void RegisterSettings(InspectronSettings settings)
{
- settings.RegisterSimple(this, () => CycleDelay, CameraName+"/Emulation", nameof(CycleDelay));
- settings.RegisterSimple(this, () => PerImageDelay, CameraName + "/Emulation", nameof(PerImageDelay));
- settings.RegisterSimple(this, () => SingleRun, CameraName + "/Emulation", nameof(SingleRun));
- settings.RegisterSimple(this, () => EmulationPath, CameraName + "/Emulation", nameof(EmulationPath));
+ settings.RegisterSimple(this, () => CycleDelay, CameraName+"/Sources/Emulation", nameof(CycleDelay));
+ settings.RegisterSimple(this, () => PerImageDelay, CameraName + "/Sources/Emulation", nameof(PerImageDelay));
+ settings.RegisterSimple(this, () => SingleRun, CameraName + "/Sources/Emulation", nameof(SingleRun));
+ settings.RegisterSimple(this, () => EmulationPath, CameraName + "/Sources/Emulation", nameof(EmulationPath));
}
}
\ No newline at end of file
diff --git a/Hawkeye.VisionBuilder.UI.Sources.IDS/Hawkeye.VisionBuilder.UI.Sources.IDS.csproj b/Hawkeye.VisionBuilder.UI.Sources.IDS/Hawkeye.VisionBuilder.UI.Sources.IDS.csproj
new file mode 100644
index 0000000..5df1e7b
--- /dev/null
+++ b/Hawkeye.VisionBuilder.UI.Sources.IDS/Hawkeye.VisionBuilder.UI.Sources.IDS.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+ uEyeDotNet.dll
+
+
+
+
diff --git a/Hawkeye.VisionBuilder.UI.Sources.IDS/IDSImageSource.cs b/Hawkeye.VisionBuilder.UI.Sources.IDS/IDSImageSource.cs
new file mode 100644
index 0000000..a8ccf07
--- /dev/null
+++ b/Hawkeye.VisionBuilder.UI.Sources.IDS/IDSImageSource.cs
@@ -0,0 +1,228 @@
+using OpenCvSharp;
+using Serilog;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Threading;
+using System.Threading.Channels;
+using System.Threading.Tasks;
+using uEye.Defines;
+using VisionBuilder.UI.Common;
+using VisionBuilder.UI.Common.RecipeProcessing;
+using Point = System.Drawing.Point;
+
+namespace Inspectron.Camera.UEye
+{
+
+ public class IDSImageSource : IImageSource, IVisionBuilderModule
+ {
+ private readonly IDSImageSourceSettings _settings;
+ private uEye.Camera _camera = null;
+
+
+ int cameraIdx;
+
+
+
+ public IDSImageSource(IDSImageSourceSettings settings)
+ {
+ _settings = settings;
+ _camera = new uEye.Camera();
+ cameraIdx = _settings.CameraId;
+ System.AppDomain.CurrentDomain.ProcessExit += AppDomain_ProcessExit;
+ }
+
+ private void AppDomain_ProcessExit(object sender, EventArgs e)
+ {
+ Close();
+ }
+
+ private Mat MemoryToImage(int idx)
+ {
+ uEye.Defines.ColorMode mode;
+ _camera.PixelFormat.Get(out mode);
+ int channels = 0;
+
+ if (mode == uEye.Defines.ColorMode.Mono8)
+ {
+ channels = 1;
+ }
+ else if (mode == uEye.Defines.ColorMode.BGR8Packed || mode == uEye.Defines.ColorMode.RGB8Packed)
+ {
+ channels = 3;
+ }
+ else if (mode == uEye.Defines.ColorMode.BGRA8Packed)
+ {
+ channels = 3;
+ }
+ else
+ {
+ throw new Exception("unknown image format");
+ }
+
+ var size = new uEye.Types.Size();
+ _camera.Memory.GetSize(idx, out size);
+ int pitch;
+ _camera.Memory.GetPitch(idx, out pitch);
+
+ Byte[] u8img;
+ _camera.Memory.CopyToArray(idx, out u8img);
+ //Console.WriteLine($"Image size: {size.Width}x{size.Height}, channels: {channels}({mode}), data size: {u8img.Length}, pitch: {pitch}");
+ //Console.ReadLine();
+ Mat mat = new Mat(size.Height,pitch, MatType.CV_8UC(channels));
+ mat.SetArray(u8img);
+ return mat;
+ }
+
+ public void Open()
+ {
+ if (_camera.IsOpened)
+ return;
+
+ uEye.Defines.Status statusRet = 0;
+
+ // Open _camera
+ statusRet = _camera.Init(cameraIdx);
+ if (statusRet != uEye.Defines.Status.Success)
+ {
+ throw new Exception("_camera initializing failed: "+statusRet);
+ }
+ uEye.Types.SensorInfo info = new uEye.Types.SensorInfo();
+ _camera.Information.GetSensorInfo(out info);
+ Console.WriteLine($"Camera {cameraIdx} opened: {info.SensorName} ({info.SensorID})");
+ _camera.Parameter.Load();
+ Console.WriteLine($"Camera {cameraIdx} parameters loaded");
+
+ _camera.Trigger.Set(uEye.Defines.TriggerMode.Continuous);
+
+ statusRet = _camera.Memory.Allocate();
+ Console.WriteLine("Memory allocated");
+ if (statusRet != uEye.Defines.Status.Success)
+ {
+ throw new Exception("Allocate Memory failed");
+
+ }
+ _camera.EventFrame += onFrameEvent;
+ try
+ {
+ _camera.Device.Feature.ShutterMode.Set(uEye.Defines.Shuttermode.Global);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ }
+
+ public void Close()
+ {
+ if (!_camera.IsOpened)
+ return;
+
+ uEye.Defines.Status statusRet;
+ statusRet = _camera.Exit();
+
+ if (statusRet != uEye.Defines.Status.Success)
+ {
+ throw new Exception("failed to close camera");
+ }
+ }
+
+
+
+ public void LoadParameters(string parameters_file)
+ {
+ uEye.Defines.Status statusRet = 0;
+
+ Int32[] memList;
+ statusRet = _camera.Memory.GetList(out memList);
+ if (statusRet != uEye.Defines.Status.Success)
+ {
+ throw new Exception("Get memory list failed: " + statusRet);
+ }
+
+ statusRet = _camera.Memory.Free(memList);
+ if (statusRet != uEye.Defines.Status.Success)
+ {
+ throw new Exception("Free memory list failed: " + statusRet);
+ }
+
+ statusRet = _camera.Parameter.Load(parameters_file);
+ if (statusRet != uEye.Defines.Status.Success)
+ {
+ throw new Exception("Loading parameter failed: " + statusRet);
+ }
+
+ uEye.Types.Size t = new uEye.Types.Size();
+
+
+ statusRet = _camera.Memory.Allocate();
+ if (statusRet != uEye.Defines.Status.SUCCESS)
+ {
+ throw new Exception("Allocate Memory failed");
+ }
+ }
+
+ public void SaveParameters(string parameters_file)
+ {
+ uEye.Defines.Status statusRet = 0;
+
+ statusRet = _camera.Parameter.Save(parameters_file);
+ if (statusRet != uEye.Defines.Status.SUCCESS)
+ {
+ throw new Exception("failed to save Parameters");
+ }
+ }
+
+
+
+
+ private void onFrameEvent(object sender, EventArgs e)
+ {
+ try
+ {
+ uEye.Camera camera = sender as uEye.Camera;
+ int s32MemId;
+ int active = (int)camera.Memory.GetActive(out s32MemId);
+ int num1 = (int)camera.Memory.Lock(s32MemId);
+ var image = this.MemoryToImage(s32MemId);
+ int num2 = (int)camera.Memory.Unlock(s32MemId);
+
+ if (!_channel.Writer.TryWrite(image))
+ {
+ Log.Warning("Image channel is full, dropping image");
+ }
+ }
+ catch (TaskCanceledException ex)
+ {
+ int num = (int)(sender as uEye.Camera).Acquisition.Stop();
+
+ }
+ }
+
+
+
+
+
+ private Channel _channel = Channel.CreateBounded(new BoundedChannelOptions(1)
+ {
+ FullMode = BoundedChannelFullMode.DropOldest,
+ SingleReader = true,
+ SingleWriter = true,
+ AllowSynchronousContinuations = true
+ });
+ public async Task GetImage(CancellationToken token)
+ {
+ return await _channel.Reader.ReadAsync(token);
+ }
+
+ public void InitializeModule()
+ {
+ Open();
+ if(!(string.IsNullOrEmpty(_settings.CameraFile)))
+ LoadParameters(_settings.CameraFile);
+ _camera.Trigger.Set(uEye.Defines.TriggerMode.Continuous);
+ _camera.Acquisition.Capture();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Hawkeye.VisionBuilder.UI.Sources.IDS/IDSImageSourceSettings.cs b/Hawkeye.VisionBuilder.UI.Sources.IDS/IDSImageSourceSettings.cs
new file mode 100644
index 0000000..9626c2a
--- /dev/null
+++ b/Hawkeye.VisionBuilder.UI.Sources.IDS/IDSImageSourceSettings.cs
@@ -0,0 +1,40 @@
+using System.Text;
+using Inspectron.Settings;
+using Inspectron.Settings.Attributes;
+using VisionBuilder.UI.Common;
+
+namespace Inspectron.Camera.UEye;
+
+public class IDSImageSourceSettings:ISettings
+{
+ public string CameraName { get; }
+
+ public IDSImageSourceSettings(string cameraName)
+ {
+ CameraName = cameraName;
+ }
+
+ [SettingPreview(typeof(IDSImageSourceSettings), nameof(CameraIdsPreview))]
+ public int CameraId { get; set; } = 0;
+
+ [File("*.ini")] public string CameraFile { get; set; } = "";
+
+ public void RegisterSettings(InspectronSettings settings)
+ {
+ settings.RegisterSimple(this, () => CameraId, $"{CameraName}/Sources/IDS", nameof(CameraId));
+ settings.RegisterSimple(this, () => CameraFile, $"{CameraName}/Sources/IDS", nameof(CameraFile));
+
+ }
+
+ public static string CameraIdsPreview(int _)
+ {
+ uEye.Info.Camera.GetCameraList(out var cameraList);
+ StringBuilder sb = new StringBuilder();
+ foreach (var camera in cameraList)
+ {
+ sb.AppendLine($"Camera ID: {camera.CameraID}, Name: {camera.SerialNumber}");
+ }
+
+ return sb.ToString();
+ }
+}
\ No newline at end of file
diff --git a/Hawkeye.VisionBuilder.UI.Sources.IDS/uEyeDotNet.dll b/Hawkeye.VisionBuilder.UI.Sources.IDS/uEyeDotNet.dll
new file mode 100644
index 0000000..1b14092
Binary files /dev/null and b/Hawkeye.VisionBuilder.UI.Sources.IDS/uEyeDotNet.dll differ
diff --git a/IDSTest/IDSTest.csproj b/IDSTest/IDSTest.csproj
new file mode 100644
index 0000000..2bbea33
--- /dev/null
+++ b/IDSTest/IDSTest.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/IDSTest/Program.cs b/IDSTest/Program.cs
new file mode 100644
index 0000000..57ad58c
--- /dev/null
+++ b/IDSTest/Program.cs
@@ -0,0 +1,13 @@
+using Inspectron.Camera.UEye;
+
+IDSImageSource imageSource = new IDSImageSource();
+
+Console.WriteLine("Opening");
+imageSource.InitializeModule();
+
+while (true)
+{
+ Console.WriteLine("Getting image");
+ var image=imageSource.GetImage(CancellationToken.None).Result;
+ image.SaveImage("test.png");
+}
\ No newline at end of file
diff --git a/VisionBuilder.UI.Camera/ModuleExtensions.cs b/VisionBuilder.UI.Camera/ModuleExtensions.cs
index bbf123a..794996d 100644
--- a/VisionBuilder.UI.Camera/ModuleExtensions.cs
+++ b/VisionBuilder.UI.Camera/ModuleExtensions.cs
@@ -1,4 +1,5 @@
using Hawkeye.VisionBuilder.UI.Sources.Emulation;
+using Inspectron.Camera.UEye;
using Ninject;
using Ninject.Extensions.ChildKernel;
using VisionBuilder.UI.Common;
@@ -12,6 +13,7 @@ public static class ModuleExtensions
{
self.Bind().ToConstant(new CameraSettings(cameraName));
self.Bind().ToConstant(new EmulationSettings(cameraName));
+ self.Bind().ToConstant(new IDSImageSourceSettings(cameraName));
self.Bind().ToSelf().InSingletonScope();
return self;
}
@@ -26,6 +28,7 @@ public static class ModuleExtensions
case CameraSettings.EImageSource.Hawkeye:
break;
case CameraSettings.EImageSource.IDS:
+ kernel.Bind().To().InSingletonScope();
break;
case CameraSettings.EImageSource.Basler:
break;
diff --git a/VisionBuilder.UI.Camera/VisionBuilder.UI.Camera.csproj b/VisionBuilder.UI.Camera/VisionBuilder.UI.Camera.csproj
index d29c8c2..149eabe 100644
--- a/VisionBuilder.UI.Camera/VisionBuilder.UI.Camera.csproj
+++ b/VisionBuilder.UI.Camera/VisionBuilder.UI.Camera.csproj
@@ -8,6 +8,7 @@
+
diff --git a/VisionBuilder.UI.Common/Extensions.cs b/VisionBuilder.UI.Common/Extensions.cs
index 312673c..c14a438 100644
--- a/VisionBuilder.UI.Common/Extensions.cs
+++ b/VisionBuilder.UI.Common/Extensions.cs
@@ -33,12 +33,13 @@ public static class Extensions
{
if (service != null)
{
+ Log.Information($"Initializing module {service.GetType().Name}");
service.InitializeModule();
}
}
catch (Exception e)
{
- Log.Error($"Error initializing module {service.GetType().Name}: {e.Message}", e);
+ Log.Error($"Error initializing module {service.GetType().Name}: {e}", e);
}
}
diff --git a/VisionBuilder.UI.Common/Processing/IImageSource.cs b/VisionBuilder.UI.Common/Processing/IImageSource.cs
index 1a17427..7a34764 100644
--- a/VisionBuilder.UI.Common/Processing/IImageSource.cs
+++ b/VisionBuilder.UI.Common/Processing/IImageSource.cs
@@ -4,6 +4,5 @@ namespace VisionBuilder.UI.Common.RecipeProcessing;
public interface IImageSource
{
- string GetName();
Task GetImage(CancellationToken token);
}
\ No newline at end of file
diff --git a/VisionBuilder.UI.IOCommander.Windows/ModuleExtensions.cs b/VisionBuilder.UI.IOCommander.Windows/ModuleExtensions.cs
index a9e421c..c4e572b 100644
--- a/VisionBuilder.UI.IOCommander.Windows/ModuleExtensions.cs
+++ b/VisionBuilder.UI.IOCommander.Windows/ModuleExtensions.cs
@@ -13,7 +13,6 @@ public static class ModuleExtensions
public static IKernel UseIOCommanderWindowsDebug(this IKernel self)
{
TypeDescriptor.AddAttributes(typeof(List), new TypeConverterAttribute(typeof(PinLabelListConverter)));
-
self.Rebind().To().InSingletonScope();
self.Bind().ToConstant(new WindowsIOCommanderDebugViewSettings());
return self;
diff --git a/VisionBuilder.UI.IOCommander/IOCommander.cs b/VisionBuilder.UI.IOCommander/IOCommander.cs
index 85934ea..7c90ede 100644
--- a/VisionBuilder.UI.IOCommander/IOCommander.cs
+++ b/VisionBuilder.UI.IOCommander/IOCommander.cs
@@ -10,7 +10,6 @@ public class IOCommander : IIOCommander
SerialPort _port;
public IOCommander(string COMPort)
{
-
_port = new SerialPort(COMPort);
_port.BaudRate = 57600;
_port.ReadTimeout = 100;
diff --git a/VisionBuilder.UI.IOCommander/Modules/IOCommanderCameraModule.cs b/VisionBuilder.UI.IOCommander/Modules/IOCommanderCameraModule.cs
index ae7ee25..a13ce58 100644
--- a/VisionBuilder.UI.IOCommander/Modules/IOCommanderCameraModule.cs
+++ b/VisionBuilder.UI.IOCommander/Modules/IOCommanderCameraModule.cs
@@ -28,7 +28,7 @@ public class IOCommanderCameraModule: IVisionBuilderModule
_recognitionControl.ImageProcessed += _recognitionControl_ImageProcessed;
_recognitionControl.SessionStarted += _recognitionControl_SessionStarted;
_recognitionControl.SessionEnded += _recognitionControl_SessionEnded;
- mainModule.OnPinChangedEvent += MainModule_OnPinChangedEvent;
+
}
@@ -93,7 +93,7 @@ public class IOCommanderCameraModule: IVisionBuilderModule
public void InitializeModule()
{
-
+ _mainModule.OnPinChangedEvent += MainModule_OnPinChangedEvent;
}
private void _recognitionControl_SessionEnded(SessionEndedEvent obj)
diff --git a/VisionBuilder.UI.IOCommander/Modules/IOCommanderModule.cs b/VisionBuilder.UI.IOCommander/Modules/IOCommanderModule.cs
index 2bbb91e..5b091c7 100644
--- a/VisionBuilder.UI.IOCommander/Modules/IOCommanderModule.cs
+++ b/VisionBuilder.UI.IOCommander/Modules/IOCommanderModule.cs
@@ -33,15 +33,12 @@ public class IOCommanderModule:IVisionBuilderModule
}
ConcurrentDictionary _pinStates = new ConcurrentDictionary();
- public event Action? OnPinChangedEvent
- {
- add => _ioCommander!.OnPinChanged += value;
- remove => _ioCommander!.OnPinChanged -= value;
- }
+ public event Action? OnPinChangedEvent = delegate { };
private void OnPinChanged(int arg1, bool arg2)
{
_pinStates.TryAdd(arg1, arg2);
_debugViewService.SetInputPinStatus(arg1, arg2);
+ OnPinChangedEvent?.Invoke(arg1, arg2);
}
public void SetOutput(int pin, bool value)
diff --git a/VisionBuilder.UI.Recipes.HawkeyeRecipe/HawkeyeRecognitionControl.cs b/VisionBuilder.UI.Recipes.HawkeyeRecipe/HawkeyeRecognitionControl.cs
index f6f090c..7360b4d 100644
--- a/VisionBuilder.UI.Recipes.HawkeyeRecipe/HawkeyeRecognitionControl.cs
+++ b/VisionBuilder.UI.Recipes.HawkeyeRecipe/HawkeyeRecognitionControl.cs
@@ -25,11 +25,6 @@ namespace VisionBuilder.UI.Recipes.HawkeyeRecipe
_loadingService = loadingService;
}
- public string GetCameraName()
- {
- return _imageSource.GetName();
- }
-
public List GetRecipesData()
{
_loadingService.StartLoading($"Loading recipes for {_recognitionConfiguration.CameraName}...");
@@ -171,7 +166,7 @@ namespace VisionBuilder.UI.Recipes.HawkeyeRecipe
AnalysisTime = sw.Elapsed,
ErrorNames = errorNames.ToList(),
HasError = errorNames.Length > 0,
- ImageSource = _imageSource.GetName(),
+ ImageSource = _recognitionConfiguration.CameraName,
ImageOriginal = _workflow.Context.LastCameraImage.ImageData,
ImageAnalysis = annotated
};
diff --git a/VisionBuilder.UI.Windows.Test/Program.cs b/VisionBuilder.UI.Windows.Test/Program.cs
index 329f0d6..aea810a 100644
--- a/VisionBuilder.UI.Windows.Test/Program.cs
+++ b/VisionBuilder.UI.Windows.Test/Program.cs
@@ -41,10 +41,10 @@ namespace VisionBuilder.UI.Windows.Test
var mainKernel = Common.VisionBuilder.CreateMainKernel(settings);
mainKernel
+ .UseConsole()
.UseIOCommander([CAMERA1])
.UseIOCommanderWindowsDebug()
.UseIOCommanderVirtualInput()
- .UseConsole()
.UseWindowsServices();
// CAMERA 1 //
diff --git a/VisionBuilder.UI.Windows/Components/PreviewWindow.cs b/VisionBuilder.UI.Windows/Components/PreviewWindow.cs
index 61f831e..7d6481d 100644
--- a/VisionBuilder.UI.Windows/Components/PreviewWindow.cs
+++ b/VisionBuilder.UI.Windows/Components/PreviewWindow.cs
@@ -1,4 +1,5 @@
-using OpenCvSharp.Extensions;
+using OpenCvSharp;
+using OpenCvSharp.Extensions;
using VisionBuilder.UI.Common.ViewModel;
namespace VisionBuilder.UI.Windows.Components;
@@ -18,7 +19,15 @@ public class PreviewWindow:PictureBox
switch (e.PropertyName)
{
case nameof(PreviewVM.ImagePreview):
- var bmp = _previewVm.ImagePreview?.ToBitmap();
+ var tmp = _previewVm.ImagePreview?.ToBitmap();
+ var bmp = new Bitmap(_previewVm.ImagePreview?.Width ?? 0, _previewVm.ImagePreview?.Height ?? 0);
+ // hack to avoid IDS image glitch
+ using (Graphics g = Graphics.FromImage(bmp))
+ {
+ g.Clear(Color.Pink);
+ g.DrawImage(tmp,0,0);
+ }
+
using (Graphics g = Graphics.FromImage(bmp))
{
// draw red border around the image if it's an error
@@ -31,6 +40,7 @@ public class PreviewWindow:PictureBox
}
}
Image = bmp;
+ Invalidate();
break;
}
diff --git a/VisionBuilder.UI.sln b/VisionBuilder.UI.sln
index 3c5a3c8..e7b750e 100644
--- a/VisionBuilder.UI.sln
+++ b/VisionBuilder.UI.sln
@@ -61,6 +61,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utility", "Utility", "{250F
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisionBuilder.UI.IOCommander.Windows", "VisionBuilder.UI.IOCommander.Windows\VisionBuilder.UI.IOCommander.Windows.csproj", "{254841AD-0706-4C92-A364-7E5DC17AF4AD}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hawkeye.VisionBuilder.UI.Sources.IDS", "Hawkeye.VisionBuilder.UI.Sources.IDS\Hawkeye.VisionBuilder.UI.Sources.IDS.csproj", "{86511F06-AABC-4F1D-AB4E-9763AE4A0EF2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F2406FBB-DFD3-4CBE-9644-A9FFC2FCBB71}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IDSTest", "IDSTest\IDSTest.csproj", "{AD1A176C-B19F-4E60-9935-728722BAE3C1}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -163,6 +169,14 @@ Global
{254841AD-0706-4C92-A364-7E5DC17AF4AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{254841AD-0706-4C92-A364-7E5DC17AF4AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{254841AD-0706-4C92-A364-7E5DC17AF4AD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {86511F06-AABC-4F1D-AB4E-9763AE4A0EF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {86511F06-AABC-4F1D-AB4E-9763AE4A0EF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {86511F06-AABC-4F1D-AB4E-9763AE4A0EF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {86511F06-AABC-4F1D-AB4E-9763AE4A0EF2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AD1A176C-B19F-4E60-9935-728722BAE3C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD1A176C-B19F-4E60-9935-728722BAE3C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD1A176C-B19F-4E60-9935-728722BAE3C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD1A176C-B19F-4E60-9935-728722BAE3C1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -185,6 +199,8 @@ Global
{FBDCC120-B6B3-4A28-8845-DF1690F619C1} = {C828783C-1CE1-4245-8731-4AE18A28F590}
{E0F75E78-F7FA-4B7D-BA5F-A8A91C0A9AD9} = {C828783C-1CE1-4245-8731-4AE18A28F590}
{254841AD-0706-4C92-A364-7E5DC17AF4AD} = {250F2B27-FA2B-4CE6-BFDE-54D0B7FC9FAF}
+ {86511F06-AABC-4F1D-AB4E-9763AE4A0EF2} = {D05689E3-04C6-4E3B-ACA7-3F4507CED4CC}
+ {AD1A176C-B19F-4E60-9935-728722BAE3C1} = {F2406FBB-DFD3-4CBE-9644-A9FFC2FCBB71}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3CE42AE5-D79F-4E97-A246-AA8FD228B677}
diff --git a/framework/Inspectron.Settings.Windows/Configuration/DefaultControlFactory.cs b/framework/Inspectron.Settings.Windows/Configuration/DefaultControlFactory.cs
index e26b4ce..cc0da14 100644
--- a/framework/Inspectron.Settings.Windows/Configuration/DefaultControlFactory.cs
+++ b/framework/Inspectron.Settings.Windows/Configuration/DefaultControlFactory.cs
@@ -43,6 +43,10 @@ public class DefaultControlFactory : IControlFactory
{
return CreateListControl(name, description, type, initialValue, valueChangedCallback, optionsWindow, settingDescription, previewLabel, getPreview);
}
+ else if (type == typeof(string) && propertyInfo.GetCustomAttribute()!=null)
+ {
+ return CreateFileControl(name, description, initialValue, valueChangedCallback, optionsWindow, settingDescription, previewLabel, getPreview, propertyInfo.GetCustomAttribute().Filter);
+ }
else if (type == typeof(string) && name.EndsWith("Path", StringComparison.OrdinalIgnoreCase))
{
return CreatePathControl(name, description, initialValue, valueChangedCallback, optionsWindow, settingDescription, previewLabel, getPreview);
@@ -156,7 +160,36 @@ public class DefaultControlFactory : IControlFactory
return CreateOuterPanel(settingDescription, previewLabel, label, textBox, browseButton);
}
+ private Control CreateFileControl(string name, string description, object initialValue, Action