나는이 주제가 2 년 이상 된 것을 알고 있지만 아마도 이것은 당신에게 흥미로울 수 있습니다.
비슷한 문제가있었습니다. 다음과 함께 시작 : 3D-Space에서 Property-Grid에서 구성 할 수있는 Point가 필요합니다. 이 경우 클래스 Koord가 생성되었습니다. 이것은 Vexel TestBock을 만들려면
(이 :-)를 위해 무엇을 알아 위키 백과 확인) (일부 3D 객체에 사용되는 : PropertyGrid가에서 그것을 변경하려면, 나는 새로운 클래스 "TypeConverter를 KoordConverter"를 생성) 나는 List of Vexels를 사용하고있다. 불행히도 내 프로그램에 TestBlocks 목록이 필요하며 Property-Grid를 통해 볼 수 있습니다.
는 맨 위의 시작하려면 :
public partial class FormMain : Form
{
private BlockProperties _bp = new BlockProperties();
public FormMain()
{
InitializeComponent();
pgProperties.SelectedObject = _bp;
}
[...]
}
더 클래스 BlockProperties 내가 안에 무엇이 당신을 보여줄 수있는 비트를 작성 TestBocks의 목록이 포함되어 있습니다.
class BlockProperties
{
public List<TestBocks> Testing { get; set; }
public BlockProperties()
{
Testing = new List<TestBocks>(3);
List<Vexel> t1 = new List<Vexel>(1);
t1.Add(new Vexel(new Koord(1,0,1), 1));
List<Vexel> t2 = new List<Vexel>(2);
t2.Add(new Vexel(new Koord(2, 0, 1), 2));
t2.Add(new Vexel(new Koord(2, 0, 2), 2));
List<Vexel> t3 = new List<Vexel>(3);
t3.Add(new Vexel(new Koord(3, 0, 1), 3));
t3.Add(new Vexel(new Koord(3, 0, 2), 3));
t3.Add(new Vexel(new Koord(3, 0, 3), 3));
TestBocks tb1 = new TestBocks();
tb1.Koords = t1;
TestBocks tb2 = new TestBocks();
tb2.Koords = t2;
TestBocks tb3 = new TestBocks();
tb3.Koords = t3;
Testing.Add(tb1);
Testing.Add(tb2);
Testing.Add(tb3);
[...]
}
[...]
}
다음
는 Vexels에서 직진
[Serializable]
public class TestBocks
{
public List<Vexel> Vexels{ get; set; }
public TestBocks()
{
Vexels = new List<Vexel>();
}
}
단순히 내 TestBlock 클래스입니다 내 프로그램에 필요한 마법의 대부분 : 심지어 수 있도록 여기)를 ToString을 (넣어 그것은 디버깅하는 동안 쉽습니다.
public class Vexel
{
private Koord _origin;
private double _extent;
public Koord Origin { get { return _origin; } set { _origin = value; } }
public double Extent { get { return _extent; } set { _extent = value; } }
public string ToString()
{
NumberFormatInfo nFormatInfo = new NumberFormatInfo
{
NumberDecimalSeparator = ".",
NumberGroupSeparator = ""
};
return String.Format(nFormatInfo, "Origin;{0};{1};{2};Extent;{3}", _origin.X, _origin.Y, _origin.Z, _extent);
}
public Vexel()
{
_origin = new Koord(0,0,0);
Extent = 0;
}
public Vexel(Koord origin, double extent)
{
//TODO do some checking
_origin = origin;
_extent = extent;
}
지금까지 PropertyGrid에서는 모든 것이 잘 작동했지만 코드를 편집 할 수 없었습니다. 클래스는 매우 간단했지만 PropertyGrid에서는 편집 할 수 없었습니다. TypeConverterClass 추가 는 TypeConverter가 쓸 수있는 가장 복잡한 코드이었다
[TypeConverter(typeof(KoordConverter))]
[Serializable]
public class Koord
{
private double p_1;
private double p_2;
private double p_3;
public Koord(double x, double y, double z)
{
this.p_1 = x;
this.p_2 = y;
this.p_3 = z;
}
public string ToString()
{
return String.Format("X;{0};Y;{1};Z;{2}", p_1, p_2, p_3);
}
public double X { get { return p_1; } }
public double Y { get { return p_2; } }
public double Z { get { return p_3; } }
}
(당신이 KOORD의 코드를 아래의 TypeConverter를 찾을 수 있습니다)이 문제를 해결했다. 아래 찾을 수 있습니다 :이 모든이 설정된 후
public class KoordConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
string text = value as string;
if (text == null)
{
return base.ConvertFrom(context, culture, value);
}
string text2 = text.Trim();
if (text2.Length == 0)
{
return null;
}
if (culture == null)
{
culture = CultureInfo.CurrentCulture;
}
char c = culture.TextInfo.ListSeparator[0];
string[] array = text2.Split(new char[]
{
c
});
int[] array2 = new int[array.Length];
TypeConverter converter = TypeDescriptor.GetConverter(typeof(int));
for (int i = 0; i < array2.Length; i++)
{
array2[i] = (int)converter.ConvertFromString(context, culture, array[i]);
}
if (array2.Length == 3)
{
return new Koord(array2[0], array2[1], array2[2]);
}
throw new ArgumentException("TextParseFailedFormat");
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == null)
{
throw new ArgumentNullException("destinationType");
}
if (value is Koord)
{
if (destinationType == typeof(string))
{
Koord Koord = (Koord)value;
if (culture == null)
{
culture = CultureInfo.CurrentCulture;
}
string separator = culture.TextInfo.ListSeparator + " ";
TypeConverter converter = TypeDescriptor.GetConverter(typeof(int));
string[] array = new string[3];
int num = 0;
array[num++] = converter.ConvertToString(context, culture, Koord.X);
array[num++] = converter.ConvertToString(context, culture, Koord.Y);
array[num++] = converter.ConvertToString(context, culture, Koord.Z);
return string.Join(separator, array);
}
if (destinationType == typeof(InstanceDescriptor))
{
Koord Koord2 = (Koord)value;
ConstructorInfo constructor = typeof(Koord).GetConstructor(new Type[]
{
typeof(double),
typeof(double),
typeof(double)
});
if (constructor != null)
{
return new InstanceDescriptor(constructor, new object[]
{
Koord2.X,
Koord2.Y,
Koord2.Z
});
}
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
{
if (propertyValues == null)
{
throw new ArgumentNullException("propertyValues");
}
object obj = propertyValues["X"];
object obj2 = propertyValues["Y"];
object obj3 = propertyValues["Z"];
if (obj == null || obj2 == null || obj3 == null || !(obj is double) || !(obj2 is double) || !(obj3 is double))
{
throw new ArgumentException("PropertyValueInvalidEntry");
}
return new Koord((double)obj, (double)obj2, (double)obj3);
}
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(Koord), attributes);
return properties.Sort(new string[]
{
"X",
"Y",
"Z"
});
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
}
는 기본적으로, 그들이 스텝 오버하면 누군가 도움 객체 (TestBlocks 각 TestBlock 내 Vexels) 는 희망의 목록을 수정 할 ploblem 없었다 이 스레드.
안부
로빈 혈액
PS : 편집은, 어쩌면 당신은 당신의 생성자 오른쪽 PropertyGrid가 아무런 문제를 얻을하지 않았다입니다!? http://i.stack.imgur.com/LD3zf.png
목록에 목록이있어서 pGrid 용 사용자 정의 편집기로 목록을 표시하고 싶습니까? –
다소 차이가 있습니다. 내 메인에 MyClassA 목록이 있습니다. MyClassA의 해당 목록은 pGrid에 바인딩됩니다. 각 MyClassA에는 MyClassB와 관련된 목록이 있습니다. 모든 MyClassB를 현재 표시되고있는 MyClassA에 대한 목록에 표시하고 사용자가 연결된 MyClassB를 편집하거나 MyClassB에 포함 된 MyClassB 목록에 새 MyClassB를 추가 할 수있게하려고합니다. 말이 돼? –
이러한 유형의 사용자 지정을 위해서는 특정 유형의 속성이 주어지면 사용자 지정 사용자 정의 컨트롤을 사용하여 표시하는 사용자 지정 그리드 용 그리드를 만들어야합니다. 내가 올바르게 이해하고 있다면. –