protected InvalidPrinterException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
}
+#if netcoreapp
+ [System.ComponentModel.TypeConverter("System.Drawing.Printing.MarginsConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")]
+#endif
public partial class Margins : System.ICloneable
{
public Margins() { }
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.ComponentModel;
using System.Globalization;
using System.Runtime.Serialization;
/// <summary>
/// Specifies the margins of a printed page.
/// </summary>
+#if netcoreapp
+ [TypeConverter("System.Drawing.Printing.MarginsConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")]
+#endif
public partial class Margins : ICloneable
{
private int _left;
public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) { throw null; }
}
}
-
+namespace System.Drawing.Printing
+{
+ public partial class MarginsConverter : System.ComponentModel.ExpandableObjectConverter
+ {
+ public MarginsConverter() { }
+ public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) { throw null; }
+ public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { throw null; }
+ public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; }
+ public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { throw null; }
+ public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary propertyValues) { throw null; }
+ public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context) { throw null; }
+ }
+}
namespace System.Security.Cryptography.X509Certificates
{
public enum X509SelectionFlag
<data name="PlatformNotSupported_X509Certificate2UI" xml:space="preserve">
<value>X509Certificate2UI is not supported on this platform.</value>
</data>
+ <data name="TextParseFailedFormat" xml:space="preserve">
+ <value>Text "{0}" cannot be parsed. The expected text format is "{1}".</value>
+ </data>
+ <data name="PropertyValueInvalidEntry" xml:space="preserve">
+ <value>IDictionary parameter contains at least one entry that is not valid. Ensure all values are consistent with the object's properties.</value>
+ </data>
</root>
\ No newline at end of file
<Compile Include="System\Drawing\IconConverter.cs" />
<Compile Include="System\Drawing\ImageConverter.cs" />
<Compile Include="System\Drawing\ImageFormatConverter.cs" />
+ <Compile Include="System\Drawing\Printing\MarginsConverter.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'">
<Reference Include="System.Buffers" />
<Reference Include="System.Runtime.Extensions" />
<Reference Include="System.Runtime.InteropServices" />
<Reference Include="System.Security.Cryptography.X509Certificates" />
+ <Reference Include="System.Text.RegularExpressions" />
<Reference Include="System.Threading" />
</ItemGroup>
</Project>
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design.Serialization;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Reflection;
+
+namespace System.Drawing.Printing
+{
+ /// <summary>
+ /// Provides a type converter to convert <see cref='System.Drawing.Printing.Margins'/> to and from various other representations, such as a string.
+ /// </summary>
+ public class MarginsConverter : ExpandableObjectConverter
+ {
+ /// <summary>
+ /// Determines if a converter can convert an object of the given source
+ /// type to the native type of the converter.
+ /// </summary>
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ if (sourceType == typeof(string))
+ {
+ return true;
+ }
+ return base.CanConvertFrom(context, sourceType);
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this converter can
+ /// convert an object to the given destination type using the context.
+ /// </summary>
+ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
+ {
+ if (destinationType == typeof(InstanceDescriptor))
+ {
+ return true;
+ }
+ return base.CanConvertTo(context, destinationType);
+ }
+
+ /// <summary>
+ /// Converts the given object to the converter's native type.
+ /// </summary>
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ if (value is string strValue)
+ {
+ string text = strValue.Trim();
+
+ if (text.Length == 0)
+ {
+ return null;
+ }
+ else
+ {
+ // Parse 4 integer values.
+ if (culture == null)
+ {
+ culture = CultureInfo.CurrentCulture;
+ }
+ char sep = culture.TextInfo.ListSeparator[0];
+ string[] tokens = text.Split(new char[] { sep });
+ int[] values = new int[tokens.Length];
+ TypeConverter intConverter = TypeDescriptor.GetConverter(typeof(int));
+ for (int i = 0; i < values.Length; i++)
+ {
+ // Note: ConvertFromString will raise exception if value cannot be converted.
+ values[i] = (int)intConverter.ConvertFromString(context, culture, tokens[i]);
+ }
+ if (values.Length != 4)
+ {
+ throw new ArgumentException(SR.Format(SR.TextParseFailedFormat, text, "left, right, top, bottom"));
+ }
+ return new Margins(values[0], values[1], values[2], values[3]);
+ }
+ }
+ return base.ConvertFrom(context, culture, value);
+ }
+
+ /// <summary>
+ /// Converts the given object to another type. The most common types to convert
+ /// are to and from a string object. The default implementation will make a call
+ /// to ToString on the object if the object is valid and if the destination
+ /// type is string. If this cannot convert to the desitnation type, this will
+ /// throw a NotSupportedException.
+ /// </summary>
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (destinationType == null)
+ {
+ throw new ArgumentNullException(nameof(destinationType));
+ }
+ if (value is Margins margins)
+ {
+ if (destinationType == typeof(string))
+ {
+ if (culture == null)
+ {
+ culture = CultureInfo.CurrentCulture;
+ }
+ string sep = culture.TextInfo.ListSeparator + " ";
+ TypeConverter intConverter = TypeDescriptor.GetConverter(typeof(int));
+ string[] args = new string[4];
+ int nArg = 0;
+
+ // Note: ConvertToString will raise exception if value cannot be converted.
+ args[nArg++] = intConverter.ConvertToString(context, culture, margins.Left);
+ args[nArg++] = intConverter.ConvertToString(context, culture, margins.Right);
+ args[nArg++] = intConverter.ConvertToString(context, culture, margins.Top);
+ args[nArg++] = intConverter.ConvertToString(context, culture, margins.Bottom);
+
+ return string.Join(sep, args);
+ }
+ if (destinationType == typeof(InstanceDescriptor))
+ {
+ ConstructorInfo ctor = typeof(Margins).GetConstructor(new Type[] {
+ typeof(int), typeof(int), typeof(int), typeof(int)});
+
+ if (ctor != null)
+ {
+ return new InstanceDescriptor(ctor, new object[] {
+ margins.Left, margins.Right, margins.Top, margins.Bottom});
+ }
+ }
+ }
+ return base.ConvertTo(context, culture, value, destinationType);
+ }
+
+ /// <summary>
+ /// Determines if changing a value on this object should require a call to
+ /// CreateInstance to create a new value.
+ /// </summary>
+ public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) => true;
+
+ /// <summary>
+ /// Creates an instance of this type given a set of property values
+ /// for the object. This is useful for objects that are immutable, but still
+ /// want to provide changable properties.
+ /// </summary>
+ public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
+ {
+ if (propertyValues == null)
+ {
+ throw new ArgumentNullException(nameof(propertyValues));
+ }
+
+ object left = propertyValues["Left"];
+ object right = propertyValues["Right"];
+ object top = propertyValues["Top"];
+ object bottom = propertyValues["Bottom"];
+
+ if (left == null || right == null || bottom == null || top == null ||
+ !(left is int) || !(right is int) || !(bottom is int) || !(top is int))
+ {
+ throw new ArgumentException(SR.Format(SR.PropertyValueInvalidEntry));
+ }
+
+ return new Margins((int)left,
+ (int)right,
+ (int)top,
+ (int)bottom);
+ }
+ }
+}
<Compile Include="System\Drawing\IconConverterTests.cs" />
<Compile Include="System\Drawing\ImageConverterTests.cs" />
<Compile Include="System\Drawing\ImageFormatConverterTests.cs" />
+ <Compile Include="System\Drawing\Printing\MarginsConverterTests.cs" />
</ItemGroup>
<ItemGroup>
<SupplementalTestData Include="$(PackagesDir)system.componentmodel.typeconverter.testdata\$(TestDataPackageVersion)\content\**\*.*">
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.ComponentModel.Design.Serialization;
+using System.Globalization;
+using Xunit;
+
+namespace System.Drawing.Printing.Tests
+{
+ public class MarginsConverterTests
+ {
+ [Fact]
+ public void CanConvertFrom()
+ {
+ MarginsConverter mc = new MarginsConverter();
+
+ // try once with then once without context
+ for (var context = new MyTypeDescriptorContext(); context != null; context = null)
+ {
+ Assert.True(mc.CanConvertFrom(context, typeof(string)));
+ Assert.False(mc.CanConvertFrom(context, typeof(Guid)));
+ Assert.False(mc.CanConvertFrom(context, typeof(object)));
+ Assert.False(mc.CanConvertFrom(context, typeof(int)));
+ }
+ }
+
+ [Fact]
+ public void CanConvertTo()
+ {
+ MarginsConverter mc = new MarginsConverter();
+
+ // try once with then once without context
+ for (var context = new MyTypeDescriptorContext(); context != null; context = null)
+ {
+ Assert.True(mc.CanConvertTo(context, typeof(string)));
+ Assert.False(mc.CanConvertTo(context, typeof(Guid)));
+ Assert.False(mc.CanConvertTo(context, typeof(object)));
+ Assert.False(mc.CanConvertTo(context, typeof(int)));
+ }
+ }
+
+ [Fact]
+ public void CreateInstance()
+ {
+ MarginsConverter mc = new MarginsConverter();
+ MyTypeDescriptorContext context = new MyTypeDescriptorContext();
+
+ IDictionary values = new Dictionary<string, int>();
+ values.Add("Left", 1);
+ values.Add("Right", 2);
+ values.Add("Top", 3);
+ Assert.Throws<ArgumentException>(() => mc.CreateInstance(context, values));
+ values.Add("Bottom", 4);
+
+ object result = mc.CreateInstance(context, values);
+ Assert.NotNull(result);
+
+ Assert.IsType<Margins>(result);
+ Margins margins = result as Margins;
+ Assert.Equal(1, margins.Left);
+ Assert.Equal(2, margins.Right);
+ Assert.Equal(3, margins.Top);
+ Assert.Equal(4, margins.Bottom);
+ }
+
+ [Fact]
+ public void GetCreateInstanceSupported()
+ {
+ MarginsConverter mc = new MarginsConverter();
+ Assert.True(mc.GetCreateInstanceSupported(null));
+ Assert.True(mc.GetCreateInstanceSupported(new MyTypeDescriptorContext()));
+ }
+
+ [Fact]
+ public void ConvertFrom()
+ {
+ MarginsConverter mc = new MarginsConverter();
+ CultureInfo culture = CultureInfo.InvariantCulture;
+
+ // try once with then once without context
+ for (var context = new MyTypeDescriptorContext(); context != null; context = null)
+ {
+ object result;
+ Assert.Equal(',', culture.TextInfo.ListSeparator[0]);
+ AssertExtensions.Throws<ArgumentException, Exception>(() => mc.ConvertFrom(context, culture, "1;2;3;4"));
+ result = mc.ConvertFrom(context, culture, "1,2,3,4");
+ Assert.IsType<Margins>(result);
+ Margins margins = result as Margins;
+ Assert.Equal(1, margins.Left);
+ Assert.Equal(2, margins.Right);
+ Assert.Equal(3, margins.Top);
+ Assert.Equal(4, margins.Bottom);
+ }
+ }
+
+ [Fact]
+ public void ConvertFrom_Throws()
+ {
+
+ MarginsConverter mc = new MarginsConverter();
+ CultureInfo culture = CultureInfo.InvariantCulture;
+
+ // try once with then once without context
+ for (var context = new MyTypeDescriptorContext(); context != null; context = null)
+ {
+ Assert.Throws<NotSupportedException>(() => mc.ConvertFrom(context, null, null));
+ Assert.Throws<NotSupportedException>(() => mc.ConvertFrom(context, culture, null));
+ Assert.Throws<NotSupportedException>(() => mc.ConvertFrom(context, culture, Guid.NewGuid()));
+ AssertExtensions.Throws<ArgumentException, Exception>(() => mc.ConvertFrom(context, null, "wrong string format"));
+ AssertExtensions.Throws<ArgumentException, Exception>(() => mc.ConvertFrom(context, culture, "wrong string format"));
+ }
+ }
+
+ [Fact]
+ public void ConvertTo()
+ {
+ MarginsConverter mc = new MarginsConverter();
+ Guid guid = Guid.NewGuid();
+ CultureInfo culture = CultureInfo.InvariantCulture;
+ Margins margins = new Margins() { Left = 1, Right = 2, Top = 3, Bottom = 4 };
+
+ // try once with then once without context
+ for (var context = new MyTypeDescriptorContext(); context != null; context = null)
+ {
+ Assert.Equal("1;2;3;4", mc.ConvertTo(context, culture, "1;2;3;4", typeof(string)));
+
+ object converted = mc.ConvertTo(context, culture, margins, typeof(string));
+ Assert.IsType<string>(converted);
+ Assert.Equal(',', culture.TextInfo.ListSeparator[0]);
+ Assert.Equal("1, 2, 3, 4", converted);
+
+ converted = mc.ConvertTo(context, culture, margins, typeof(InstanceDescriptor));
+ Assert.IsType<InstanceDescriptor>(converted);
+ Assert.Equal(new object[] { 1, 2, 3, 4 }, ((InstanceDescriptor)converted).Arguments);
+
+ Assert.Throws<NotSupportedException>(() => mc.ConvertTo(context, culture, new object(), typeof(object)));
+ Assert.Throws<NotSupportedException>(() => mc.ConvertTo(context, culture, 12, typeof(int)));
+ Assert.Throws<NotSupportedException>(() => mc.ConvertTo(context, culture, guid, typeof(Guid)));
+ }
+ }
+
+ private class MyTypeDescriptorContext : ITypeDescriptorContext
+ {
+ public IContainer Container => null;
+ public object Instance { get { return null; } }
+ public PropertyDescriptor PropertyDescriptor { get { return null; } }
+ public bool OnComponentChanging() { return true; }
+ public void OnComponentChanged() { }
+ public object GetService(Type serviceType) { return null; }
+ }
+ }
+}