diff --git a/src/System.Windows.Forms.Primitives/src/System/ComponentModel/TypeConverterHelper.cs b/src/System.Windows.Forms.Primitives/src/System/ComponentModel/TypeConverterHelper.cs index 5ea877d26b6..ee06aa1fdf5 100644 --- a/src/System.Windows.Forms.Primitives/src/System/ComponentModel/TypeConverterHelper.cs +++ b/src/System.Windows.Forms.Primitives/src/System/ComponentModel/TypeConverterHelper.cs @@ -7,6 +7,15 @@ namespace System.ComponentModel; internal static class TypeConverterHelper { + // Feature switch, when set to true, used for trimming to access ComponentModel in a trim safe manner + [FeatureSwitchDefinition("System.Windows.Forms.Primitives.TypeConverterHelper.UseComponentModelRegisteredTypes")] +#pragma warning disable IDE0075 // Simplify conditional expression - the simpler expression is hard to read + private static bool UseComponentModelRegisteredTypes { get; } = + AppContext.TryGetSwitch("System.Windows.Forms.Primitives.TypeConverterHelper.UseComponentModelRegisteredTypes", out bool isEnabled) + ? isEnabled + : false; +#pragma warning restore IDE0075 + /// /// Converts the given text to list of objects, using the specified context and culture information. /// @@ -28,7 +37,18 @@ internal static class TypeConverterHelper return false; } - TypeConverter converter = TypeDescriptor.GetConverter(typeof(T)); + TypeConverter converter; + if (!UseComponentModelRegisteredTypes) + { + converter = TypeDescriptor.GetConverter(typeof(T)); + } + else + { + // Call the trim safe API + TypeDescriptor.RegisterType(); + converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(T)); + } + for (int i = 0; i < output.Length; i++) { // Note: ConvertFromString will raise exception if value cannot be converted. diff --git a/src/System.Windows.Forms/src/Resources/SR.resx b/src/System.Windows.Forms/src/Resources/SR.resx index f5642df6a2c..30ef02209f0 100644 --- a/src/System.Windows.Forms/src/Resources/SR.resx +++ b/src/System.Windows.Forms/src/Resources/SR.resx @@ -6968,6 +6968,12 @@ Stack trace where the illegal operation occurred was: Binding operations are not supported when application trimming is enabled. - Using the BinaryFormatter is not supported. + Using the BinaryFormatter is not supported in trimmed applications. + + + '{0}' is not supported in trimmed applications. + + + Design time features are not supported. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf index 7439652146b..c7eff3368fa 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.cs.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - Použití BinaryFormatter není podporováno. + Using the BinaryFormatter is not supported in trimmed applications. + Použití BinaryFormatter není podporováno. @@ -1662,6 +1662,11 @@ Objekt child není podřízeným ovládacím prvkem tohoto nadřazeného objektu. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. Vyvolá se, když je změněna vlastnost AutoSize. @@ -4639,6 +4644,11 @@ Chcete-li nahradit toto výchozí dialogové okno, nastavte popisovač události Umožňuje uživateli procházet webové stránky uvnitř formuláře. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. Operace {0} se součástí se nezdařila. Generovaný kód chyby je 0x{1:X}. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf index ac1d9cc723d..51f4f0bd5e9 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.de.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - Die Verwendung von BinaryFormatter wird nicht unterstützt. + Using the BinaryFormatter is not supported in trimmed applications. + Die Verwendung von BinaryFormatter wird nicht unterstützt. @@ -1662,6 +1662,11 @@ "child" ist kein untergeordnetes Steuerelement dieses übergeordneten Elements. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. Tritt ein, wenn sich die AutoSize-Eigenschaft geändert hat. @@ -4639,6 +4644,11 @@ Behandeln Sie das DataError-Ereignis, um dieses Standarddialogfeld zu ersetzen.< Ermöglicht dem Benutzer das Besuchen von Webseiten im Formular. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. Fehler beim {0}-Vorgang für die Komponente. Fehlercode: 0x{1:X}. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf index 211ae25d438..596790609fd 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.es.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - No se admite el uso de BinaryFormatter. + Using the BinaryFormatter is not supported in trimmed applications. + No se admite el uso de BinaryFormatter. @@ -1662,6 +1662,11 @@ 'child' no es un control secundario de este primario. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. Tiene lugar cuando la propiedad AutoSize ha cambiado. @@ -4639,6 +4644,11 @@ Para reemplazar este cuadro de diálogo predeterminado controle el evento DataEr Permite al usuario explorar páginas web dentro del formulario. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. Error de la operación {0} en el componente con el código de error 0x{1:X}. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf index 8bb7b3d2373..c48d441d8d9 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.fr.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - L’utilisation de BinaryFormatter n’est pas prise en charge. + Using the BinaryFormatter is not supported in trimmed applications. + L’utilisation de BinaryFormatter n’est pas prise en charge. @@ -1662,6 +1662,11 @@ 'child' n'est pas un contrôle enfant de ce parent. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. Se produit lorsque la propriété AutoSize est modifiée. @@ -4639,6 +4644,11 @@ Pour remplacer cette boîte de dialogue par défaut, traitez l'événement DataE Permet à l'utilisateur de parcourir les pages web au sein de votre formulaire. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. L'opération {0} sur le composant a échoué avec le code d'erreur 0x{1:X}. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf index 58bbd065dae..1e3f4b2d396 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.it.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - L'uso di BinaryFormatter non è supportato. + Using the BinaryFormatter is not supported in trimmed applications. + L'uso di BinaryFormatter non è supportato. @@ -1662,6 +1662,11 @@ 'child' non è un controllo figlio di questo elemento. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. Generato alla modifica della proprietà AutoSize. @@ -4639,6 +4644,11 @@ Per sostituire questa finestra di dialogo predefinita, gestire l'evento DataErro Consente all'utente di esplorare pagine Web all'interno del form. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. Operazione {0} sul componente non riuscita con codice di errore 0x{1:X}. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf index 229622b644a..53ad806ede7 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.ja.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - BinaryFormatter の使用はサポートされていません。 + Using the BinaryFormatter is not supported in trimmed applications. + BinaryFormatter の使用はサポートされていません。 @@ -1662,6 +1662,11 @@ '子' はこの親の子コントロールではありません。 + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. AutoSize プロパティが変更したときに発生します。 @@ -4639,6 +4644,11 @@ To replace this default dialog please handle the DataError event. フォーム内の Web ページをユーザーが参照できるようにします。 + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. コンポーネントの操作 {0} がエラー コード 0x{1:X} を生成して、成功しませんでした。 diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf index 82c8c1736e1..560ef573cf4 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.ko.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - BinaryFormatter 사용은 지원되지 않습니다. + Using the BinaryFormatter is not supported in trimmed applications. + BinaryFormatter 사용은 지원되지 않습니다. @@ -1662,6 +1662,11 @@ 'child'는 이 부모의 자식 컨트롤이 아닙니다. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. AutoSize 속성이 변경되면 발생합니다. @@ -4639,6 +4644,11 @@ To replace this default dialog please handle the DataError event. 사용자가 폼에서 웹 페이지를 찾을 수 있습니다. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. 구성 요소의 {0} 작업이 실패했습니다. 오류 코드 0x{1:X}를 생성합니다. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf index 639072eced8..a23be18f171 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.pl.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - Używanie elementu BinaryFormatter nie jest obsługiwane. + Using the BinaryFormatter is not supported in trimmed applications. + Używanie elementu BinaryFormatter nie jest obsługiwane. @@ -1662,6 +1662,11 @@ Element 'child' nie jest formantem podrzędnym dla tego formantu. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. Występuje, gdy właściwość AutoSize zostanie zmieniona. @@ -4639,6 +4644,11 @@ Aby zamienić to domyślne okno dialogowe, obsłuż zdarzenie DataError.Umożliwia użytkownikowi przeglądanie stron sieci Web w formularzu. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. Niepowodzenie operacji {0} dla składnika, kod błędu 0x{1:X}. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf index cbb3bf00de7..97771b571ff 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.pt-BR.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - Não há suporte para o uso do BinaryFormatter. + Using the BinaryFormatter is not supported in trimmed applications. + Não há suporte para o uso do BinaryFormatter. @@ -1662,6 +1662,11 @@ 'child' não é um controle filho deste pai. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. Ocorre quando a propriedade AutoSize é alterada. @@ -4639,6 +4644,11 @@ Para substituir a caixa de diálogo padrão, manipule o evento DataError.Permite que o usuário navegue pelas páginas da Web dentro do formulário. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. A operação {0} no componente não teve êxito, gerando o código de erro 0x{1:X}. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf index da78ce370ab..a70b3b9cb82 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.ru.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - Использование BinaryFormatter не поддерживается. + Using the BinaryFormatter is not supported in trimmed applications. + Использование BinaryFormatter не поддерживается. @@ -1662,6 +1662,11 @@ 'child' не является дочерним элементом управления этого родительского элемента. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. Возникает при изменении свойства AutoSize. @@ -4639,6 +4644,11 @@ To replace this default dialog please handle the DataError event. Позволяет пользователю просматривать веб-страницы внутри формы. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. Невозможно выполнить операцию {0} для компонента; генерируется код ошибки 0x{1:X}. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf index 32497d77636..aaaa8f5ace1 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.tr.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - BinaryFormatter kullanımı desteklenmiyor. + Using the BinaryFormatter is not supported in trimmed applications. + BinaryFormatter kullanımı desteklenmiyor. @@ -1662,6 +1662,11 @@ 'alt' bu üstün alt denetimi değil. + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. AutoSize özelliği değiştiğinde gerçekleşir. @@ -4639,6 +4644,11 @@ Bu varsayılan iletişim kutusunu değiştirmek için, lütfen DataError olayın Kullanıcıların formunuzdaki Web sayfalarına gitmesine olanak tanır. + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. Bileşen üzerindeki {0} işlemi başarılı olmadı, oluşturulan hata kodu 0x{1:X}. diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf index 6b7677a6fce..a576ececcfd 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hans.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - 不支持使用 BinaryFormatter。 + Using the BinaryFormatter is not supported in trimmed applications. + 不支持使用 BinaryFormatter。 @@ -1662,6 +1662,11 @@ “child”不是此父级的子控件。 + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. 在 AutoSize 属性更改时发生。 @@ -4639,6 +4644,11 @@ To replace this default dialog please handle the DataError event. 允许用户在窗体内浏览网页。 + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. 该组件上的 {0} 操作失败,生成错误代码 0x{1:X}。 diff --git a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf index 243fe4bf281..279724c8190 100644 --- a/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf +++ b/src/System.Windows.Forms/src/Resources/xlf/SR.zh-Hant.xlf @@ -288,8 +288,8 @@ - Using the BinaryFormatter is not supported. - 不支援使用 BinaryFormatter。 + Using the BinaryFormatter is not supported in trimmed applications. + 不支援使用 BinaryFormatter。 @@ -1662,6 +1662,11 @@ 'child' 不是此父系的子控制項。 + + '{0}' is not supported in trimmed applications. + '{0}' is not supported in trimmed applications. + + Occurs when the AutoSize property has changed. 當 AutoSize 屬性變更時發生。 @@ -4639,6 +4644,11 @@ To replace this default dialog please handle the DataError event. 讓使用者可以瀏覽表單內部的 Web 網頁。 + + Design time features are not supported. + Design time features are not supported. + + Operation {0} on the component did not succeed, generating the error code 0x{1:X}. 元件的作業 {0} 失敗,產生錯誤碼 0x{1:X}。 diff --git a/src/System.Windows.Forms/src/System/Drawing/Design/UITypeEditor.cs b/src/System.Windows.Forms/src/System/Drawing/Design/UITypeEditor.cs index fd19c73e1c0..98b8c0c0735 100644 --- a/src/System.Windows.Forms/src/System/Drawing/Design/UITypeEditor.cs +++ b/src/System.Windows.Forms/src/System/Drawing/Design/UITypeEditor.cs @@ -14,8 +14,23 @@ namespace System.Drawing.Design; /// public class UITypeEditor { + // Feature switch, when set to false, UITypeEditor is not supported in trimmed applications. + [FeatureSwitchDefinition("System.Drawing.Design.UITypeEditor.IsSupported")] +#pragma warning disable IDE0075 // Simplify conditional expression - the simpler expression is hard to read + private static bool IsSupported { get; } = + AppContext.TryGetSwitch("System.Drawing.Design.UITypeEditor.IsSupported", out bool isSupported) + ? isSupported + : true; +#pragma warning restore IDE0075 + static UITypeEditor() { + // Trimming doesn't support UITypeEditor + if (!IsSupported) + { + return; + } + // Our set of intrinsic editors. Hashtable intrinsicEditors = new Hashtable { @@ -47,6 +62,14 @@ static UITypeEditor() TypeDescriptor.AddEditorTable(typeof(UITypeEditor), intrinsicEditors); } + public UITypeEditor() + { + if (!IsSupported) + { + throw new NotSupportedException(string.Format(SR.ControlNotSupportedInTrimming, nameof(UITypeEditor))); + } + } + /// /// Determines if drop-down editors should be resizable by the user. /// diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/Control.ActiveXImpl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/Control.ActiveXImpl.cs index 81fc7d48bb0..0d13bf9afc5 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/Control.ActiveXImpl.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ActiveX/Control.ActiveXImpl.cs @@ -136,6 +136,15 @@ private sealed unsafe partial class ActiveXImpl : MarshalByRefObject, IWindowTar private short _accelCount = -1; private RECT* _adjustRect; // temporary rect used during OnPosRectChange && SetObjectRects + // Feature switch, when set to false, ActiveX is not supported in trimmed applications. + [FeatureSwitchDefinition("System.Windows.Forms.ActiveXImpl.IsSupported")] +#pragma warning disable IDE0075 // Simplify conditional expression - the simpler expression is hard to read + private static bool IsSupported { get; } = + AppContext.TryGetSwitch("System.Windows.Forms.ActiveXImpl.IsSupported", out bool isSupported) + ? isSupported + : true; +#pragma warning restore IDE0075 + /// /// Creates a new ActiveXImpl. /// @@ -1035,6 +1044,11 @@ internal void Load(IStream* stream) /// internal unsafe void Load(IPropertyBag* propertyBag, IErrorLog* errorLog) { + if (!IsSupported) + { + throw new NotSupportedException(string.Format(SR.ControlNotSupportedInTrimming, nameof(ActiveXImpl))); + } + PropertyDescriptorCollection props = TypeDescriptor.GetProperties( _control, [DesignerSerializationVisibilityAttribute.Visible]); @@ -1134,6 +1148,11 @@ bool SetValue(PropertyDescriptor currentProperty, object data) #pragma warning disable SYSLIB0011 // Type or member is obsolete if (!success) { + if (!DataObject.ComposedDataObject.EnableUnsafeBinaryFormatterInNativeObjectSerialization) + { + throw new NotSupportedException(SR.BinaryFormatterNotSupported); + } + stream.Position = 0; deserialized = new BinaryFormatter().Deserialize(stream); } @@ -1420,6 +1439,11 @@ internal unsafe HRESULT QuickActivate(QACONTAINER* pQaContainer, QACONTROL* pQaC { Type? eventInterface = null; + if (!IsSupported) + { + throw new NotSupportedException(string.Format(SR.ControlNotSupportedInTrimming, nameof(ActiveXImpl))); + } + // Get the first declared interface, if any. if (controlType.GetCustomAttributes(inherit: false).FirstOrDefault() is { } comSourceInterfaces) @@ -1469,6 +1493,11 @@ internal void Save(IStream* stream, BOOL fClearDirty) /// internal void Save(IPropertyBag* propertyBag, BOOL clearDirty, BOOL saveAllProperties) { + if (!IsSupported) + { + throw new NotSupportedException(string.Format(SR.ControlNotSupportedInTrimming, nameof(ActiveXImpl))); + } + PropertyDescriptorCollection props = TypeDescriptor.GetProperties( _control, [DesignerSerializationVisibilityAttribute.Visible]); @@ -1503,6 +1532,11 @@ internal void Save(IPropertyBag* propertyBag, BOOL clearDirty, BOOL saveAllPrope { stream.SetLength(0); + if (!DataObject.ComposedDataObject.EnableUnsafeBinaryFormatterInNativeObjectSerialization) + { + throw new NotSupportedException(SR.BinaryFormatterNotSupported); + } + #pragma warning disable SYSLIB0011 // Type or member is obsolete new BinaryFormatter().Serialize(stream, sourceValue); #pragma warning restore diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs index e0192a6d6f4..a2a345ccd0b 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs @@ -56,6 +56,22 @@ public unsafe partial class Control : "Makes double buffered controls non-double buffered"); #endif + // Feature switch, when set to false, design time features of controls are not supported in trimmed applications. + [FeatureSwitchDefinition("System.Windows.Forms.Control.AreDesignTimeFeaturesSupported")] +#pragma warning disable IDE0075 // Simplify conditional expression - the simpler expression is hard to read + internal static bool AreDesignTimeFeaturesSupported { get; } = + AppContext.TryGetSwitch("System.Windows.Forms.Control.AreDesignTimeFeaturesSupported", out bool isEnabled) + ? isEnabled + : true; + + // Feature switch, when set to true, used for trimming to access ComponentModel in a trim safe manner + [FeatureSwitchDefinition("System.Windows.Forms.Control.UseComponentModelRegisteredTypes")] + internal static bool UseComponentModelRegisteredTypes { get; } = + AppContext.TryGetSwitch("System.Windows.Forms.Control.UseComponentModelRegisteredTypes", out bool isEnabled) + ? isEnabled + : false; +#pragma warning restore IDE0075 + private static readonly uint WM_GETCONTROLNAME = PInvoke.RegisterWindowMessage("WM_GETCONTROLNAME"); private static readonly uint WM_GETCONTROLTYPE = PInvoke.RegisterWindowMessage("WM_GETCONTROLTYPE"); @@ -977,6 +993,12 @@ internal bool BecomingActiveControl [EditorBrowsable(EditorBrowsableState.Never)] public void ResetBindings() { + if (!Binding.IsSupported) + { + // This gets called with Dispose that needs to be handled, a throwing is not appropriate in this case. + return; + } + ControlBindingsCollection? bindings = (ControlBindingsCollection?)Properties.GetObject(s_bindingsProperty); bindings?.Clear(); } @@ -1029,7 +1051,6 @@ internal BindingContext? BindingContextInternal public virtual BindingContext? BindingContext { get => BindingContextInternal; - [RequiresUnreferencedCode(IBindableComponent.ComponentModelTrimIncompatibilityMessage)] set => BindingContextInternal = value; } @@ -1670,6 +1691,11 @@ public ControlBindingsCollection DataBindings { get { + if (!Binding.IsSupported) + { + throw new NotSupportedException(SR.BindingNotSupported); + } + ControlBindingsCollection? bindings = (ControlBindingsCollection?)Properties.GetObject(s_bindingsProperty); if (bindings is null) { @@ -13006,6 +13032,11 @@ void IArrangedElement.SetBounds(Rectangle bounds, BoundsSpecified specified) if (site is not null && site.DesignMode && site.TryGetService(out changeService)) { + if (!AreDesignTimeFeaturesSupported) + { + throw new NotSupportedException(SR.DesignTimeFeaturesNotSupported); + } + sizeProperty = TypeDescriptor.GetProperties(this)[PropertyNames.Size]; locationProperty = TypeDescriptor.GetProperties(this)[PropertyNames.Location]; Debug.Assert(sizeProperty is not null && locationProperty is not null, "Error retrieving Size/Location properties on Control."); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonBase.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonBase.cs index c5642fe1f79..6ceb9b5a715 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonBase.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/Buttons/ButtonBase.cs @@ -155,6 +155,11 @@ public override Color BackColor { if (value != Color.Empty) { + if (!AreDesignTimeFeaturesSupported) + { + throw new NotSupportedException(SR.DesignTimeFeaturesNotSupported); + } + PropertyDescriptor? pd = TypeDescriptor.GetProperties(this)["UseVisualStyleBackColor"]; pd?.SetValue(this, false); } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListControl/ListControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListControl/ListControl.cs index cbc24978dd5..47a1bb7b32c 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListControl/ListControl.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ListControl/ListControl.cs @@ -135,6 +135,11 @@ private TypeConverter? DisplayMemberConverter { get { + if (!Binding.IsSupported) + { + throw new NotSupportedException(SR.BindingNotSupported); + } + if (_displayMemberConverter is null) { PropertyDescriptorCollection? props = DataManager?.GetItemProperties(); @@ -422,6 +427,11 @@ private void DataManager_ItemChanged(object? sender, ItemChangedEventArgs e) { if (item is not null && !string.IsNullOrEmpty(field)) { + if (!Binding.IsSupported) + { + throw new NotSupportedException(SR.BindingNotSupported); + } + try { // if we have a dataSource, then use that to display the string @@ -527,7 +537,15 @@ private protected int FindStringInternal(string? str, IList? items, int startInd } // Try Formatter.FormatObject - s_stringTypeConverter ??= TypeDescriptor.GetConverter(typeof(string)); + if (!UseComponentModelRegisteredTypes) + { + s_stringTypeConverter ??= TypeDescriptor.GetConverter(typeof(string)); + } + else + { + // Call the trim safe API + s_stringTypeConverter ??= TypeDescriptor.GetConverterFromRegisteredType(typeof(string)); + } try { diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/OpacityConverter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/OpacityConverter.cs index a8b00bf80d0..44873ec40ed 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/OpacityConverter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/OpacityConverter.cs @@ -45,7 +45,15 @@ public override bool CanConvertFrom(ITypeDescriptorContext? context, Type source double percent; try { - percent = (double)TypeDescriptor.GetConverter(typeof(double)).ConvertFrom(context, culture, text)!; + if (!Control.UseComponentModelRegisteredTypes) + { + percent = (double)TypeDescriptor.GetConverter(typeof(double)).ConvertFrom(context, culture, text)!; + } + else + { + // Call the trim safe API + percent = (double)TypeDescriptor.GetConverterFromRegisteredType(typeof(double)).ConvertFrom(context, culture, text)!; + } // Assume they meant a percentage if it is > 1.0, else they actually // typed the correct double. diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs index a865ad63dfc..cb64774db4f 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs @@ -387,7 +387,6 @@ public override BindingContext? BindingContext return null; } - [RequiresUnreferencedCode(IBindableComponent.ComponentModelTrimIncompatibilityMessage)] set { if (Properties.GetObject(s_propBindingContext) != value) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripMenuItem.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripMenuItem.cs index ad48f03ebcc..d9c732a1ce5 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripMenuItem.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripMenuItem.cs @@ -196,6 +196,12 @@ protected override AccessibleObject CreateAccessibilityInstance() private void Initialize() { + if (Control.UseComponentModelRegisteredTypes) + { + // Register the type with the ComponentModel so as to be trim safe + TypeDescriptor.RegisterType(); + } + Overflow = ToolStripItemOverflow.Never; MouseDownAndUpMustBeInSameItem = false; SupportsDisabledHotTracking = true; @@ -1108,7 +1114,15 @@ internal void SetNativeTargetWindow(IWin32Window window) return string.Empty; } - return TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString(context: null, CultureInfo.CurrentUICulture, shortcutKeys); + if (!Control.UseComponentModelRegisteredTypes) + { + return TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString(context: null, CultureInfo.CurrentUICulture, shortcutKeys); + } + else + { + // Call the trim safe API, Keys type has been registered at Initialize() + return TypeDescriptor.GetConverterFromRegisteredType(typeof(Keys)).ConvertToString(context: null, CultureInfo.CurrentUICulture, shortcutKeys); + } } internal override bool IsBeingTabbedTo() diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/BindableComponent.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/BindableComponent.cs index 4c48f8718dd..efc2f2c4a41 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/BindableComponent.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/BindableComponent.cs @@ -28,7 +28,6 @@ public BindingContext? BindingContext { get => _bindingContext ??= []; - [RequiresUnreferencedCode(IBindableComponent.ComponentModelTrimIncompatibilityMessage)] set { if (!Equals(_bindingContext, value)) diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/Binding.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/Binding.cs index 18be17725c4..feb69b76710 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/Binding.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/Binding.cs @@ -12,10 +12,14 @@ namespace System.Windows.Forms; [TypeConverter(typeof(ListBindingConverter))] public partial class Binding { + // Feature switch, when set to false, binding is not supported in trimmed applications. [FeatureSwitchDefinition("System.Windows.Forms.Binding.IsSupported")] #pragma warning disable IDE0075 // Simplify conditional expression - the simpler expression is hard to read - internal static bool IsSupported => AppContext.TryGetSwitch("System.Windows.Forms.Binding.IsSupported", out bool isSupported) ? isSupported : true; -#pragma warning restore IDE0075 //Simplify conditional expression + internal static bool IsSupported { get; } = + AppContext.TryGetSwitch("System.Windows.Forms.Binding.IsSupported", out bool isSupported) + ? isSupported + : true; +#pragma warning restore IDE0075 private BindingManagerBase? _bindingManagerBase; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/BindingContext.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/BindingContext.cs index d5cfc8ae817..629a3786ce2 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/BindingContext.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/BindingContext.cs @@ -18,6 +18,7 @@ public partial class BindingContext : ICollection /// /// Initializes a new instance of the System.Windows.Forms.BindingContext class. /// + [RequiresUnreferencedCode(IBindableComponent.ComponentModelTrimIncompatibilityMessage)] public BindingContext() { _listManagers = []; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/IBindableComponent.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/IBindableComponent.cs index 04d63a1559d..2e3d3f65d5b 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/IBindableComponent.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataBinding/IBindableComponent.cs @@ -12,7 +12,6 @@ public interface IBindableComponent : IComponent BindingContext? BindingContext { get; - [RequiresUnreferencedCode(ComponentModelTrimIncompatibilityMessage)] set; } } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/ImageIndexConverter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/ImageIndexConverter.cs index 1f70178af39..c215332af24 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/ImageIndexConverter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/ImageIndexConverter.cs @@ -12,6 +12,15 @@ namespace System.Windows.Forms; /// public class ImageIndexConverter : Int32Converter { + // Feature switch, when set to false, ImageIndexConverter is not supported in trimmed applications. + [FeatureSwitchDefinition("System.Windows.Forms.ImageIndexConverter.IsSupported")] +#pragma warning disable IDE0075 // Simplify conditional expression - the simpler expression is hard to read + private static bool IsSupported { get; } = + AppContext.TryGetSwitch("System.Windows.Forms.ImageIndexConverter.IsSupported", out bool isSupported) + ? isSupported + : true; +#pragma warning restore IDE0075 + /// /// Gets a value that indicates whether a value is valid in /// the collection. @@ -83,6 +92,11 @@ public class ImageIndexConverter : Int32Converter /// public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context) { + if (!IsSupported) + { + throw new NotSupportedException(string.Format(SR.ControlNotSupportedInTrimming, nameof(ImageIndexConverter))); + } + if (context is not null && context.Instance is not null) { object? instance = context.Instance; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Internal/Formatter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Internal/Formatter.cs index 6174cbafaf2..bd2f770d1dd 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Internal/Formatter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Internal/Formatter.cs @@ -26,7 +26,6 @@ internal static class Formatter /// If the caller is expecting a nullable value back, we must also re-wrap the final result /// inside a nullable value before returning. /// - [RequiresUnreferencedCode(ComponentModelTrimIncompatibilityMessage)] public static object? FormatObject( object? value, Type targetType, @@ -84,7 +83,6 @@ internal static class Formatter /// - Uses TypeConverters or IConvertible where appropriate /// - Throws a FormatException is no suitable conversion can be found /// - [RequiresUnreferencedCode(ComponentModelTrimIncompatibilityMessage)] private static object? FormatObjectInternal( object? value, Type targetType, @@ -137,13 +135,34 @@ internal static class Formatter // The converters for properties should take precedence. Unfortunately, we don't know whether we have one. Check vs. the // type's TypeConverter. We're punting the case where the property-provided converter is the same as the type's converter. Type sourceType = value.GetType(); - TypeConverter sourceTypeTypeConverter = TypeDescriptor.GetConverter(sourceType); + + TypeConverter sourceTypeTypeConverter; + if (!Control.UseComponentModelRegisteredTypes) + { + sourceTypeTypeConverter = TypeDescriptor.GetConverter(sourceType); + } + else + { + // Call the trim safe API + sourceTypeTypeConverter = TypeDescriptor.GetConverterFromRegisteredType(sourceType); + } + if (sourceConverter is not null && sourceConverter != sourceTypeTypeConverter && sourceConverter.CanConvertTo(targetType)) { return sourceConverter.ConvertTo(context: null, GetFormatterCulture(formatInfo), value, targetType); } - TypeConverter targetTypeTypeConverter = TypeDescriptor.GetConverter(targetType); + TypeConverter targetTypeTypeConverter; + if (!Control.UseComponentModelRegisteredTypes) + { + targetTypeTypeConverter = TypeDescriptor.GetConverter(targetType); + } + else + { + // Call the trim safe API + targetTypeTypeConverter = TypeDescriptor.GetConverterFromRegisteredType(targetType); + } + if (targetConverter is not null && targetConverter != targetTypeTypeConverter && targetConverter.CanConvertFrom(sourceType)) { return targetConverter.ConvertFrom(context: null, GetFormatterCulture(formatInfo), value); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/ContainerControl.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/ContainerControl.cs index 3f7be28dfd4..1b96f5cca01 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/ContainerControl.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/ContainerControl.cs @@ -266,7 +266,6 @@ public override BindingContext? BindingContext return bm; } - [RequiresUnreferencedCode(IBindableComponent.ComponentModelTrimIncompatibilityMessage)] set => base.BindingContext = value; } diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/SplitContainer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/SplitContainer.cs index 16e3905f122..31041bfed87 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/SplitContainer.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/SplitContainer.cs @@ -220,7 +220,6 @@ public override BindingContext? BindingContext return BindingContextInternal; } - [RequiresUnreferencedCode(IBindableComponent.ComponentModelTrimIncompatibilityMessage)] set { BindingContextInternal = value; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIWindowDialog.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIWindowDialog.cs index 2904f9e4053..ab15190cf44 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIWindowDialog.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIWindowDialog.cs @@ -11,6 +11,15 @@ internal sealed partial class MdiWindowDialog : Form private TableLayoutPanel _okCancelTableLayoutPanel; private Form? _active; + // Feature switch, when set to false, MdiWindowDialog is not supported in trimmed applications. + [FeatureSwitchDefinition("System.Windows.Forms.MdiWindowDialog.IsSupported")] +#pragma warning disable IDE0075 // Simplify conditional expression - the simpler expression is hard to read + private static bool IsSupported { get; } = + AppContext.TryGetSwitch("System.Windows.Forms.MdiWindowDialog.IsSupported", out bool isSupported) + ? isSupported + : true; +#pragma warning restore IDE0075 + public MdiWindowDialog() : base() { @@ -74,6 +83,11 @@ private void ItemList_selectedIndexChanged(object? source, EventArgs e) [MemberNotNull(nameof(_okCancelTableLayoutPanel))] private void InitializeComponent() { + if (!IsSupported) + { + throw new NotSupportedException(string.Format(SR.ControlNotSupportedInTrimming, nameof(MdiWindowDialog))); + } + System.ComponentModel.ComponentResourceManager resources = new(typeof(MdiWindowDialog)); _itemList = new ListBox(); _okButton = new Button(); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.ComposedDataObject.NativeDataObjectToWinFormsAdapter.cs b/src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.ComposedDataObject.NativeDataObjectToWinFormsAdapter.cs index 7cba3de8ad5..eac17f197f0 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.ComposedDataObject.NativeDataObjectToWinFormsAdapter.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/OLE/DataObject.ComposedDataObject.NativeDataObjectToWinFormsAdapter.cs @@ -16,9 +16,12 @@ public unsafe partial class DataObject { internal unsafe partial class ComposedDataObject { + // Feature switch, when set to false, BinaryFormatter is not supported in trimmed applications. + // This field, using the default BinaryFormatter switch, is used to control trim warnings related to using BinaryFormatter in WinForms trimming. + // The trimmer will generate a warning when set to true and will not generate a warning when set to false. [FeatureSwitchDefinition("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization")] #pragma warning disable IDE0075 // Simplify conditional expression - the simpler expression is hard to read - private static bool EnableUnsafeBinaryFormatterInNativeObjectSerialization { get; } = + internal static bool EnableUnsafeBinaryFormatterInNativeObjectSerialization { get; } = AppContext.TryGetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", out bool isEnabled) ? isEnabled : true; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Panels/TableLayoutPanel/TableLayoutSettings.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Panels/TableLayoutPanel/TableLayoutSettings.cs index c45c5d3ecd2..03df7cf50ef 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/Panels/TableLayoutPanel/TableLayoutSettings.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/Panels/TableLayoutPanel/TableLayoutSettings.cs @@ -466,7 +466,18 @@ internal TableLayoutPanelCellPosition GetPositionFromControl(IArrangedElement? e void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) { - TypeConverter converter = TypeDescriptor.GetConverter(this); + TypeConverter converter; + if (!Control.UseComponentModelRegisteredTypes) + { + converter = TypeDescriptor.GetConverter(this); + } + else + { + // Call the trim safe API + TypeDescriptor.RegisterType(); + converter = TypeDescriptor.GetConverterFromRegisteredType(this); + } + string? stringVal = converter.ConvertToInvariantString(this); if (!string.IsNullOrEmpty(stringVal)) @@ -485,6 +496,11 @@ internal List GetControlsInformation() { List controlsInfo = new(Owner!.Children.Count); + if (Control.UseComponentModelRegisteredTypes) + { + TypeDescriptor.RegisterType(); + } + foreach (IArrangedElement element in Owner.Children) { if (element is Control c) @@ -493,7 +509,17 @@ internal List GetControlsInformation() // We need to go through the PropertyDescriptor for the Name property // since it is shadowed. - PropertyDescriptor? prop = TypeDescriptor.GetProperties(c)["Name"]; + PropertyDescriptor? prop; + if (!Control.UseComponentModelRegisteredTypes) + { + prop = TypeDescriptor.GetProperties(c)["Name"]; + } + else + { + // Call the trim safe API + prop = TypeDescriptor.GetPropertiesFromRegisteredType(c)["Name"]; + } + if (prop is not null && prop.PropertyType == typeof(string)) { controlInfo.Name = prop.GetValue(c); diff --git a/src/System.Windows.Forms/tests/ComDisabledTests/Control.ActiveXImplTests.cs b/src/System.Windows.Forms/tests/ComDisabledTests/Control.ActiveXImplTests.cs new file mode 100644 index 00000000000..86087a502be --- /dev/null +++ b/src/System.Windows.Forms/tests/ComDisabledTests/Control.ActiveXImplTests.cs @@ -0,0 +1,61 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections; +using System.Runtime.Serialization; +using Windows.Win32.Foundation; +using Windows.Win32.System.Com; + +namespace System.Windows.Forms.Tests; + +public unsafe partial class Control_ActiveXImplTests +{ + [WinFormsFact] + public void ActiveXImpl_SaveLoad_BinaryFormatterProperty_FormatterEnabled() + { + using MyControl control = new(); + + // We need to have a type that doesn't have a TypeConverter that implements ISerializable to hit the + // BinaryFormatter code path. + SerializableStruct myValue = new() { Value = "HelloThere" }; + control.SerializableValue = myValue; + IPersistStreamInit.Interface persistStream = control; + + using MemoryStream memoryStream = new(); + using var istream = memoryStream.ToIStream(); + HRESULT hr = persistStream.Save(istream.Value, fClearDirty: BOOL.FALSE); + Assert.True(hr.Succeeded); + control.SerializableValue = default; + + istream.Value->Seek(0, SeekOrigin.Begin); + hr = persistStream.Load(istream.Value); + Assert.True(hr.Succeeded); + Assert.Equal(myValue, control.SerializableValue); + } + + private class MyControl : Control + { + public SerializableStruct SerializableValue { get; set; } + } + + private class BinaryFormatterPropertiesControl : Control + { + public Hashtable Table { get; set; } + } + + [Serializable] + public struct SerializableStruct : ISerializable + { + public string Value { get; set; } + + public readonly void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue(nameof(Value), Value, typeof(string)); + } + + private SerializableStruct(SerializationInfo serializationInfo, StreamingContext streamingContext) + { + Value = (string)serializationInfo.GetValue(nameof(Value), typeof(string)); + } + } +} diff --git a/src/System.Windows.Forms/tests/IntegrationTests/TrimTest/TrimTest.csproj b/src/System.Windows.Forms/tests/IntegrationTests/TrimTest/TrimTest.csproj index bbcb598a8bf..f71fe3efc27 100644 --- a/src/System.Windows.Forms/tests/IntegrationTests/TrimTest/TrimTest.csproj +++ b/src/System.Windows.Forms/tests/IntegrationTests/TrimTest/TrimTest.csproj @@ -22,4 +22,38 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Control.ActiveXImplTests.cs b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Control.ActiveXImplTests.cs index 820fdb84e1b..d93546c542a 100644 --- a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Control.ActiveXImplTests.cs +++ b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/Control.ActiveXImplTests.cs @@ -32,30 +32,6 @@ public void ActiveXImpl_SaveLoad_RoundTrip_FormatterDisabled() Assert.Equal(Color.Bisque, control.BackColor); } - [WinFormsFact] - public void ActiveXImpl_SaveLoad_BinaryFormatterProperty_FormatterEnabled() - { - using BinaryFormatterScope formatterScope = new(enable: true); - using MyControl control = new(); - - // We need to have a type that doesn't have a TypeConverter that implements ISerializable to hit the - // BinaryFormatter code path. - SerializableStruct myValue = new() { Value = "HelloThere" }; - control.SerializableValue = myValue; - IPersistStreamInit.Interface persistStream = control; - - using MemoryStream memoryStream = new(); - using var istream = memoryStream.ToIStream(); - HRESULT hr = persistStream.Save(istream.Value, fClearDirty: BOOL.FALSE); - Assert.True(hr.Succeeded); - control.SerializableValue = default; - - istream.Value->Seek(0, SeekOrigin.Begin); - hr = persistStream.Load(istream.Value); - Assert.True(hr.Succeeded); - Assert.Equal(myValue, control.SerializableValue); - } - [WinFormsFact] public void ActiveXImpl_SaveLoad_BinaryFormatterProperty_FormatterDisabled() {