From 6cd10c9f3a45919cdb8cbc5a60f1daa4536177ab Mon Sep 17 00:00:00 2001 From: Leaf Shi Date: Fri, 8 Sep 2023 01:31:38 -0700 Subject: [PATCH] Port DataGridViewComboBoxColumnDesigner to runtime --- .../src/System.Design.Forwards.cs | 1 + .../DataGridViewComboBoxColumnDesigner.cs | 115 ++++++++++++++++++ .../DesignSurface/DemoConsole/MainForm.cs | 5 +- .../Forms/Design/DesignerAttributeTests.cs | 1 - 4 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DataGridViewComboBoxColumnDesigner.cs diff --git a/src/System.Design/src/System.Design.Forwards.cs b/src/System.Design/src/System.Design.Forwards.cs index 207af0196c7..54b5a484f35 100644 --- a/src/System.Design/src/System.Design.Forwards.cs +++ b/src/System.Design/src/System.Design.Forwards.cs @@ -39,6 +39,7 @@ [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.ComboBoxDesigner))] [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.DataGridViewDesigner))] [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.DataGridViewColumnDesigner))] +[assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.DataGridViewComboBoxColumnDesigner))] [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.DateTimePickerDesigner))] [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.FormDocumentDesigner))] [assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.FlowPanelDesigner))] diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DataGridViewComboBoxColumnDesigner.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DataGridViewComboBoxColumnDesigner.cs new file mode 100644 index 00000000000..a81480ca39b --- /dev/null +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DataGridViewComboBoxColumnDesigner.cs @@ -0,0 +1,115 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; +using System.Collections; + +namespace System.Windows.Forms.Design; + +/// +/// Provides a base designer for data grid view columns. +/// +internal class DataGridViewComboBoxColumnDesigner : DataGridViewColumnDesigner +{ + private static BindingContext? s_bindingContext; + + private string ValueMember + { + get + { + DataGridViewComboBoxColumn dataGridViewComboBoxColumn = (DataGridViewComboBoxColumn)Component; + return dataGridViewComboBoxColumn.ValueMember; + } + set + { + DataGridViewComboBoxColumn dataGridViewComboBoxColumn = (DataGridViewComboBoxColumn)Component; + if (dataGridViewComboBoxColumn.DataSource is null) + { + return; + } + + if (ValidDataMember(dataGridViewComboBoxColumn.DataSource, dataMember: value)) + { + dataGridViewComboBoxColumn.ValueMember = value; + } + } + } + + private string DisplayMember + { + get + { + DataGridViewComboBoxColumn dataGridViewComboBoxColumn = (DataGridViewComboBoxColumn)Component; + return dataGridViewComboBoxColumn.DisplayMember; + } + set + { + DataGridViewComboBoxColumn dataGridViewComboBoxColumn = (DataGridViewComboBoxColumn)Component; + if (dataGridViewComboBoxColumn.DataSource is null) + { + return; + } + + if (ValidDataMember(dataGridViewComboBoxColumn.DataSource, value)) + { + dataGridViewComboBoxColumn.DisplayMember = value; + } + } + } + + private bool ShouldSerializeDisplayMember() + { + DataGridViewComboBoxColumn dataGridViewComboBoxColumn = (DataGridViewComboBoxColumn)Component; + return !string.IsNullOrEmpty(dataGridViewComboBoxColumn.DisplayMember); + } + + private bool ShouldSerializeValueMember() + { + DataGridViewComboBoxColumn dataGridViewComboBoxColumn = (DataGridViewComboBoxColumn)Component; + return !string.IsNullOrEmpty(dataGridViewComboBoxColumn.ValueMember); + } + + private static bool ValidDataMember(object dataSource, string dataMember) + { + if (string.IsNullOrEmpty(dataMember)) + { + // A null string is a valid value + return true; + } + + s_bindingContext ??= new BindingContext(); + + BindingMemberInfo bindingMemberInfo = new BindingMemberInfo(dataMember); + BindingManagerBase bindingManagerBase; + + try + { + bindingManagerBase = s_bindingContext[dataSource, bindingMemberInfo.BindingPath]; + } + catch (ArgumentException) + { + return false; + } + + return bindingManagerBase is null + ? false + : (bindingManagerBase.GetItemProperties()?[bindingMemberInfo.BindingField]) is not null; + } + + protected override void PreFilterProperties(IDictionary properties) + { + base.PreFilterProperties(properties); + + PropertyDescriptor? property = (PropertyDescriptor?)properties["ValueMember"]; + if (property is not null) + { + properties["ValueMember"] = TypeDescriptor.CreateProperty(typeof(DataGridViewComboBoxColumnDesigner), property, Array.Empty()); + } + + property = (PropertyDescriptor?)properties["DisplayMember"]; + if (property is not null) + { + properties["DisplayMember"] = TypeDescriptor.CreateProperty(typeof(DataGridViewComboBoxColumnDesigner), property, Array.Empty()); + } + } +} diff --git a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs index 0f3ee6cad43..7840bd60d89 100644 --- a/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs +++ b/src/System.Windows.Forms/tests/IntegrationTests/DesignSurface/DemoConsole/MainForm.cs @@ -258,7 +258,10 @@ private void CreateDesignSurface(int n) BindingSource bindingSource = surface.CreateComponent(); bindingSource.DataSource = new List { "a1", "b2", "c3", "d4", "e5", "f6" }; listBox.DataSource = bindingSource; - surface.CreateControl(new Size(200, 150), new Point(470, 220)); + DataGridView dataGridView = surface.CreateControl(new Size(200, 150), new Point(470, 220)); + DataGridViewComboBoxColumn comboBoxColumn = surface.CreateComponent(); + comboBoxColumn.HeaderText = "Column1"; + dataGridView.Columns.AddRange([comboBoxColumn]); } break; diff --git a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Design/DesignerAttributeTests.cs b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Design/DesignerAttributeTests.cs index 3c8568de57f..fcbc8113d48 100644 --- a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Design/DesignerAttributeTests.cs +++ b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Design/DesignerAttributeTests.cs @@ -24,7 +24,6 @@ public class DesignerAttributeTests // https://github.com/dotnet/winforms/issues/2411 "System.Windows.Forms.Design.AxDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Windows.Forms.Design.AxHostDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", - "System.Windows.Forms.Design.DataGridViewComboBoxColumnDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Windows.Forms.Design.StatusBarDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Windows.Forms.Design.WebBrowserDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",