V>>а не могли бы Вы выслать исходные коды на [chandif собака gmail точка com]
_FR>Всё необходимое в посте есть В чём сложности?
лень, было соображалку включать, но спасибо разобрался)))...
такой вопрос, а как можно для своего класса два различных TypeConvertera ?
те я хочу получить что то типа
[TypeConverter(typeof(PropertySorter))] -- для управления сортировкой
[TypeConverter(typeof(ComponentTypeConverter))] -- для управления видимостью и редактированием
public class MyClass : Component
{
...
}
public class ComponentTypeConverter : CustomPropertiesTypeConverter<MyClass>
{
...
}
class PropertySorter : ExpandableObjectConverter
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, vehfl, Вы писали:
V>>такой вопрос, а как можно для своего класса два различных TypeConvertera ?
_FR>И какой из двух должен будет быть создан при таком вот вызове: _FR>
что то я не совсем понял((...
подозреваю что какой вопрос такой и ответ
пояснения чего я хочу получить в итоге:
если коротко хочется чтобы мой класс обладал возможностью указания сортировки полей посредством задания атрибута TypeConverter с параметром PropertySorter, а также возможностью регулировки видимости и возможностью редактирования полей согласно описанному вами примеру
в данный момент я не совсем понимаю как это я могу сделать((
так как, когда пишу
[TypeConverter(typeof(ComponentTypeConverter))]
[TypeConverter(typeof(PropertySorter))]
public class MyClass
или
[TypeConverter(typeof(ComponentTypeConverter), (typeof(PropertySorter))]
public class MyClass
Здравствуйте, vehfl, Вы писали:
V>пояснения чего я хочу получить в итоге:
Это понятно. Я пытался показать, почему подобное невозможно. У типа может быть только один конвертер (в данный момент времени), поэтому надо либо в одном конверторе реализовать всю необходимую функциональность, либо поиграть с ICustomTypeDescriptor-ом, что бы в зависимости от ситуации он возвращал тот или иной конвертер.
... << RSDN@Home 1.2.0 alpha 4 rev. 1048>>
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, vehfl, Вы писали:
V>>пояснения чего я хочу получить в итоге:
_FR>Это понятно. Я пытался показать, почему подобное невозможно. У типа может быть только один конвертер (в данный момент времени), поэтому надо либо в одном конверторе реализовать всю необходимую функциональность, либо поиграть с ICustomTypeDescriptor-ом, что бы в зависимости от ситуации он возвращал тот или иной конвертер.
понятно...
но это какое то странное ограничение... либо реализовано как то не так )
потому что я реализовал то, что мне нужно следующим образом:
[TypeConverter(typeof(PropertySorter))]
public class MyClass
...
[TypeConverter(typeof(ComponentTypeConverter))]
public class MyClassChild : MyClass
в итоге атрибуты в MyClassChild сортируются согласно PropertySorter, и я могу регулировать видимость и редактируемость атрибутов посредством ComponentTypeConverter
Здравствуйте, vehfl, Вы писали:
V>в итоге атрибуты в MyClassChild сортируются согласно PropertySorter, и я могу регулировать видимость и редактируемость атрибутов посредством ComponentTypeConverter
Здравствуйте, Владимир Л., Вы писали:
ВЛ>Есть ли фозможность менять цвет, фонт у отдельных строк PropertyGrid? ВЛ>Например, некоторые свойства пользователь должен поменять, они пусть будут синие. ВЛ>Некоторые — трогать нежелательно (но можно), пусть будут серыми и т.п.
Спасибо за статью. А никто не подскажет, можно ли перехватить управление в момент, когда PropertyGrid только собирается вызвать SetValue у соответствующего дескриптора? Есть событие PropertyValueChanged, но, к сожалению, PropertyValueChanging отсутствует Покопался Рефлектором в кишках, ничего интересного не нашел
Есть ли решение для форматирования отображаемых в гриде строк?
например, требуется отобразить значение типа double, с применением строки форматирования "F2"...
АК>Аннотация: АК>Как управлять видимостью свойства в зависимости от значения другого свойства?
Пытался прикрутить к кастомному WWF Activity. Вылезли следующие баги. 1.
Код Activity
[Serializable]
public enum TestEnum
{
Value1,
Value2
}
[Serializable]
[TypeConverter(typeof(ExpandableObjectConverter))]
public class C1
{
private string s1 = "", s2 = "";
public string S1
{
get { return s1; }
set { s1 = value; }
}
public string S2
{
get { return s2; }
set { s2 = value; }
}
}
[Serializable]
[TypeConverter(typeof(ExpandableObjectConverter))]
public class C2
{
private int n1 = 0, n2 = 0;
public int N1
{
get { return n1; }
set { n1 = value; }
}
public int N2
{
get { return n2; }
set { n2 = value; }
}
}
public partial class Activity1 : Activity, ICustomTypeDescriptor
{
public Activity1()
{
InitializeComponent();
Param1 = new C1();
Param2 = new C2();
}
public static DependencyProperty ZZEnumValueProperty =
DependencyProperty.Register("ZZEnumValue", typeof(TestEnum), typeof(Activity1));
[TypeConverter(typeof(EnumTypeConverter))]
public TestEnum ZZEnumValue
{
get
{
return ((TestEnum)(GetValue(ZZEnumValueProperty)));
}
set
{
SetValue(ZZEnumValueProperty, value);
}
}
public static DependencyProperty Param1Property =
DependencyProperty.Register("Param1", typeof(C1), typeof(Activity1));
[DynamicPropertyFilter("ZZEnumValue", "Value1")]
public C1 Param1
{
get
{
return ((C1)(GetValue(Param1Property)));
}
set
{
SetValue(Param1Property, value);
}
}
public static DependencyProperty Param2Property =
DependencyProperty.Register("Param2", typeof(C2), typeof(Activity1));
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[DynamicPropertyFilter("ZZEnumValue", "Value2")]
public C2 Param2
{
get
{
return ((C2)(GetValue(Param2Property)));
}
set
{
SetValue(Param2Property, value);
}
}
#region ICustomTypeDescriptor Members
private PropertyDescriptorCollection GetFilteredProperties(Attribute[] attributes)
{
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this, attributes, true);
PropertyDescriptorCollection finalProps =
new PropertyDescriptorCollection(new PropertyDescriptor[0]);
foreach (PropertyDescriptor pd in pdc)
{
bool include = false;
bool dynamic = false;
foreach (Attribute a in pd.Attributes)
{
DynamicPropertyFilterAttribute dpf = a as DynamicPropertyFilterAttribute;
if (dpf != null)
{
dynamic = true;
PropertyDescriptor temp = pdc[dpf.PropertyName];
if (dpf.ShowOn.IndexOf(temp.GetValue(this).ToString()) > -1)
{
include = true;
}
}
}
if (!dynamic || include)
{
finalProps.Add(pd);
}
}
return finalProps;
}
public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(this, true);
}
public string GetClassName()
{
return TypeDescriptor.GetClassName(this, true);
}
public string GetComponentName()
{
return TypeDescriptor.GetComponentName(this, true);
}
public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}
public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this, true);
}
public PropertyDescriptor GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(this, true);
}
public object GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes, true);
}
public EventDescriptorCollection GetEvents()
{
return TypeDescriptor.GetEvents(this, true);
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return GetFilteredProperties(attributes);
}
public PropertyDescriptorCollection GetProperties()
{
return GetFilteredProperties(new Attribute[0]);
}
public object GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}
#endregion
}
Компилруем, добавляем в проект workflow. Кидаем на нее это самое Activity.
Устанавливаем ZZEnumValue в Value2 и соответвенно устанавливаем атрибуты Param2 в какие-нить значения.
Закрываем дизайнер Workflow.
Открываем дизайнер Workflow.
Получаем исключение:
Error Loading Workflow .... The type Activity1 has no property named Param2
Проблема в выделенной строке. До присваивания ZZEnumValue значения Value2 свойство Param2 дизайнер не видит. Скорей всего потому что мы его вручную скрыли. Если вручную переместить выделенную строку выше
this.activity11.Param2 = c21;
или же переименовать ZZEnumValue в AAEnumValue(т.к. присваитваются свойства по алфавиту, и соотвественно значение AAEnumValue будет присвоено первым)
то все заработает.
Вообще интересно бы до причин докопаться. 2.
Если имеем в Activity "управляющее" свойство типа
public enum TestEnum
{
GetValue,
GetValuesCount,
GetValuesList
}
и соотвественно несколько "управляемых" по значениям этого enum, то реализация метода GetFilteredProperties будет сбоить:
if (dpf.ShowOn.IndexOf(temp.GetValue(this).ToString()) > -1)
свойство "управляемое" значением GetValue будет показываться всегда.
В общем я переписал так:
private PropertyDescriptorCollection GetFilteredProperties(Attribute[] attributes)
{
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this, attributes, true);
PropertyDescriptorCollection finalProps =
new PropertyDescriptorCollection(new PropertyDescriptor[0]);
foreach (PropertyDescriptor pd in pdc)
{
bool include = false;
bool dynamic = false;
foreach (Attribute a in pd.Attributes)
{
DynamicPropertyFilterAttribute dpf = a as DynamicPropertyFilterAttribute;
if (dpf != null)
{
dynamic = true;
PropertyDescriptor temp = pdc[dpf.PropertyName];
string[] values = dpf.ShowOn.Split(',');
string currentValue = temp.GetValue(this).ToString();
foreach (string avalue in values)
{
if (avalue.Trim()==currentValue)
{
include = true;
break;
}
}
break;
}
}
if (!dynamic || include)
{
finalProps.Add(pd);
}
}
return finalProps;
}