diff Source/ComponentModel/Design/TypePicker.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/ComponentModel/Design/TypePicker.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,282 @@
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.ComponentModel.Design.Data;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+using System.Windows.Forms.Design;
+
+namespace BLToolkit.ComponentModel.Design
+{
+	[DesignTimeVisible(false)]
+	[ToolboxItem(false)]
+	public partial class TypePicker : UserControl
+	{
+		public TypePicker()
+		{
+			InitializeComponent();
+
+			if (!_size.IsEmpty)
+				Size = _size;
+		}
+
+		ITypeResolutionService     _typeResolutionService;
+		IWindowsFormsEditorService _windowsFormsEditorService;
+		IServiceProvider           _serviceProvider;
+
+		Type                       _resultType;
+		Predicate<Type>            _filter;
+
+		static Size _size;
+
+		private T GetService<T>()
+		{
+			return (T)_serviceProvider.GetService(typeof(T));
+		}
+
+		public Type PickType(IServiceProvider serviceProvider, Type type, Predicate<Type> filter)
+		{
+			_resultType = type;
+			_filter     = filter;
+
+			_serviceProvider           = serviceProvider;
+			_typeResolutionService     = GetService<ITypeResolutionService>();
+			_windowsFormsEditorService = GetService<IWindowsFormsEditorService>();
+
+			InitUI  ();
+			AddTypes();
+
+			if (_windowsFormsEditorService != null)
+				_windowsFormsEditorService.DropDownControl(this);
+
+			return _resultType;
+		}
+
+		private void InitUI()
+		{
+			IUIService uiService = GetService<IUIService>();
+
+			if (uiService != null)
+			{
+				object color = uiService.Styles["VsColorPanelHyperLink"];
+
+				if (color is Color)
+					addNewLinkLabel.LinkColor = (Color)color;
+
+				color = uiService.Styles["VsColorPanelHyperLinkPressed"];
+
+				if (color is Color)
+					addNewLinkLabel.ActiveLinkColor = (Color)color;
+			}
+
+			// Add None node.
+			//
+			TreeNode node = new TypeNode("None");
+
+			treeView.Nodes.Add(node);
+			treeView.SelectedNode = node;
+		}
+
+		private TypeNode GetTypeNode(DataSourceDescriptor ds)
+		{
+			Type type = null;
+
+			if (_typeResolutionService != null)
+				type = _typeResolutionService.GetType(ds.TypeName);
+
+			try
+			{
+				if (type == null)
+					type = Type.GetType(ds.TypeName, true);
+			}
+			catch
+			{
+				return null;
+			}
+
+			if (_filter != null && _filter(type) == false)
+				return null;
+
+			return new TypeNode(ds.Name, type);
+		}
+
+		private void AddGroup(DataSourceGroup group)
+		{
+			TreeNode groupNode = null;
+
+			foreach (DataSourceDescriptor d in group.DataSources)
+			{
+				if (d == null)
+					continue;
+
+				TypeNode node = GetTypeNode(d);
+
+				if (node == null)
+					continue;
+
+				if (group.IsDefault)
+				{
+					treeView.Nodes.Add(node);
+				}
+				else
+				{
+					if (groupNode == null)
+						treeView.Nodes.Add(groupNode = new TreeNode(group.Name, 2, 2));
+
+					groupNode.Nodes.Add(node);
+				}
+
+				if (_resultType == node.Type)
+					treeView.SelectedNode = node;
+			}
+		}
+
+		private void AddTypes()
+		{
+			DataSourceProviderService dspService = GetService<DataSourceProviderService>();
+
+			if (dspService == null || !dspService.SupportsAddNewDataSource)
+				return;
+
+			DataSourceGroupCollection dataSources = null;
+
+			try
+			{
+				dataSources = dspService.GetDataSources();
+			}
+			catch (Exception ex)
+			{
+				IUIService ui = GetService<IUIService>();
+
+				string message = 
+					"Cant retrieve Data Source Collection: " + ex.Message +
+					"\nCheck the 'Properties\\DataSources' folder of your project.";
+
+				if (ui != null)
+					ui.ShowError(ex, message);
+				else
+					MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+			}
+
+			if (dataSources == null)
+				return;
+
+			foreach (DataSourceGroup group in dataSources)
+				if (group != null)
+					AddGroup(group);
+		}
+
+		private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
+		{
+			if (e.Node is TypeNode)
+			{
+				_resultType = ((TypeNode)e.Node).Type;
+				_windowsFormsEditorService.CloseDropDown();
+			}
+		}
+
+		private void addNewLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+		{
+			using (GetTypeDialog dlg = new GetTypeDialog(_serviceProvider, typeof (object), _filter))
+			{
+				IUIService   uiService = GetService<IUIService>();
+				IWin32Window owner     = uiService == null? null: uiService.GetDialogOwnerWindow();
+				DialogResult result    = dlg.ShowDialog(owner);
+
+				if (result == DialogResult.OK && dlg.ResultType != null)
+				{
+					_resultType = dlg.ResultType;
+
+					SaveType(_resultType);
+
+					_windowsFormsEditorService.CloseDropDown();
+				}
+			}
+		}
+
+		private void TypePicker_Resize(object sender, EventArgs e)
+		{
+			_size = Size;
+		}
+
+		private void SaveType(Type type)
+		{
+			DataSourceProviderService dspService = GetService<DataSourceProviderService>();
+
+			if (dspService == null || !dspService.SupportsAddNewDataSource)
+				return;
+
+			try
+			{
+				const string vs9TypeName = "Microsoft.VSDesigner.VSDesignerPackage.IGenericObjectDataSourcesService, Microsoft.VSDesigner, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+				const string vs8TypeName = "Microsoft.VSDesigner.VSDesignerPackage.IGenericObjectDataSourcesService, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+
+				Type   serviceType = Type.GetType(vs9TypeName) ?? Type.GetType(vs8TypeName);
+
+				if (serviceType == null)
+					return;
+
+				object service = _serviceProvider.GetService(serviceType);
+
+				if (service == null)
+					return;
+
+				MethodInfo mi = serviceType.GetMethod("AddGenericObjectDataSource");
+
+				mi.Invoke(service, new object[] { _serviceProvider, null, type });
+			}
+			catch (Exception ex)
+			{
+				IUIService ui = GetService<IUIService>();
+
+				if (ui != null)
+					ui.ShowError(ex);
+				else
+					MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+			}
+		}
+
+		internal class TypeNode : TreeNode
+		{
+			public TypeNode(string name)
+				: base(name, 0, 0)
+			{
+				_isSelectable = true;
+			}
+
+			public TypeNode(string name, Type type)
+				: this(name, type, true)
+			{
+			}
+
+			public TypeNode(string name, Type type, bool isSelectable)
+				: base(name, 3, 3)
+			{
+				_type         = type;
+				_isSelectable = isSelectable;
+			}
+
+			private bool _isSelectable;
+			public  bool  IsSelectable
+			{
+				get { return _isSelectable;  }
+				set { _isSelectable = value; }
+			}
+
+			private readonly Type _type;
+			public           Type  Type
+			{
+				get { return _type; }
+			}
+		}
+
+		class NewLink : LinkLabel
+		{
+			protected override bool IsInputKey(Keys key)
+			{
+				return key == Keys.Return? true: base.IsInputKey(key);
+			}
+		}
+	}
+}