Ich habe eine Anwendung mit zwei Editoren. Nennen wir sie Kundeneditor (CEditor) und Modelleditor (MEditor).
Wir verschaffen Ihnen mehr Kontext, in der Hoffnung, dass daraus kein Roman entsteht:
Den gibt es eine Konfiguration, die von beiden Editoren bearbeitet werden kann. Es gibt eine Eigenschaft eines Baumknotens, die früher vom CEeditor und MEditor bearbeitet werden konnte. Nennen wir diese Eigenschaft
Pickers.
Die Bearbeitung wird dynamisch zur Verfügung gestellt mit einer Ableitung von CollectionEditor.
Die Konfiguration wird als XML serialisiert.
Die
Pickers-Eigenschaft ist eine Sammlung von Elementen, sie können vom Typ PickerA sein , PickerB, PickerC usw. aber alle erben von
PickerBase und sie teilen eine gemeinsame Eigenschaft
Searcher, die in
PickerBase definiert ist.
In der Vergangenheit war das Browsable-Attribut dieser Eigenschaft auf
true gesetzt, was dazu führte, dass die Eigenschaft zur Bearbeitung im benutzerdefinierten
CollectionEditor angezeigt wurde. Beide Editoren verwendeten dasselbe Steuerelement. Nennen wir es
ResponsiveDesigner, um eine Baumansicht zu hosten, in der bei Auswahl eines bestimmten Knotens ein Eigenschaftenraster ausgefüllt wird und wenn der Benutzer auf die
Auswahl klickt > Eigenschaft „…“ würde sich der benutzerdefinierte
CollectionEditor öffnen und dem Benutzer die Möglichkeit bieten, die Auswahl zu bearbeiten.
Jetzt möchte ich den
Sucher Nur Eigenschaft dieser verschiedenen Picker-Typen im CEditor sichtbar (und damit bearbeitbar) sein, nicht im MEditor.
Dazu habe ich ein neues Attribut BrowsableInEditor mit einer (BrowsableIn)-Enumeration mit den Werten erstellt:< /p>
- Beide
- CEdtiorOnly
- MEditorOnly
Im Inneren Klasse
PickerBase Ich habe das Attribut Browsable der Eigenschaft
Searcher auf „false“ gesetzt und den BrowsableInEditor( hinzugefügt.
)-Attribut.
Es gab eine vorhandene Klasse:
Code: Select all
public class PickerConfigurationEditor : CollectionEditor
{
public PickerConfigurationEditor(Type type) : base(type) { }
protected override object CreateInstance(Type itemType) => base.CreateInstance(itemType);
protected override Type[] CreateNewItemTypes() =>
...
}
Ich habe eine neue Klasse hinzugefügt, die von
CollectionEditor erbt und durch Überprüfung des Besitzers des Editors feststellen kann, ob sie sich im Kundeneditor- oder Modelleditormodus befindet:
Code: Select all
public abstract class ContextAwareCollectionEditor : CollectionEditor
{
private Form ParentForm { get; set; }
protected ContextAwareCollectionEditor(Type type) : base(type) { }
protected override object CreateInstance(Type itemType)
{
var instance = base.CreateInstance(itemType);
if (instance is IContextAwareTypeDescriptor list && ParentForm is {Owner: IContextAwareDesigner contextAwareDesigner})
{
list.CustomerEditorMode = contextAwareDesigner.CustomerEditorMode ;
}
return instance;
}
protected override CollectionForm CreateCollectionForm()
{
var collectionForm = base.CreateCollectionForm();
ParentForm = collectionForm.FindForm();
return collectionForm;
}
}
Jetzt erbt der
PickerConfigurationEditor von diesem
ContextAwareCollectionEditor:
öffentliche Klasse PickerConfigurationEditor: ContextAwareCollectionEditor
{
public PickerConfigurationEditor (Typtyp): base(type) {
Code: Select all
protected override Type[] CreateNewItemTypes() =>
...
Sehen wir uns auch an, wie der Editor zugeordnet ist:
Code: Select all
[Editor("xyz.PickerConfigurationEditor , xyz.UiExtensions", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public sealed class PickersList : List
, IContextAwareTypeDescriptor
{
public bool CustomerEditorMode { get; set; }
...
public PropertyDescriptorCollection GetProperties()
{
var pds = new PropertyDescriptorCollection(null);
for (var i = 0; i < Count; i++)
{
pds.Add(new PickerBaseDescriptor(this, i, CustomerEditorMode));
}
return pds;
}
(IContextAwareTypeDescriptor erbt von ICustomTypeDescriptor und fügt eine CustomerEditorMode-Eigenschaft hinzu)
Und der
PickerBaseDescriptor sieht so aus:
öffentliche versiegelte Klasse PickerBaseDescriptor: PropertyDescriptor
{
private readonly PickersList _pickersList;
private readonly int _index = -1;
private readonly bool _customerEditorMode;
Code: Select all
public PickerBaseDescriptor(PickersList list, int idx, bool customerEditorMode) :
base("#" + idx.ToString(), null)
{
_pickersList = list;
_index = idx;
_customerEditorMode= customerEditorMode;
}
public override bool IsBrowsable
{
get
{
var browsableAttr = Attributes.OfType
().FirstOrDefault();
if (browsableAttr?.Browsable == true) return true;
var editorAttr = Attributes.OfType
().FirstOrDefault();
return editorAttr?.BrowsableIn == BrowsableIn.Both || editorAttr?.BrowsableIn == BrowsableIn.KpfOnly && _customerEditorMode
|| editorAttr?.BrowsableIn == BrowsableIn.DesignerOnly && !_customerEditorMode;
}
}
public override AttributeCollection Attributes => new AttributeCollection(null);
...
Das Problem ist, dass das nicht funktioniert. Wenn ich in der Methode
GetProperties von PickersList einen Haltepunkt setze, wird dieser nicht erreicht.
Die Frage ist also entweder, was mache ich falsch oder vielleicht TL ;DR: Wie kann ich eine Eigenschaft einer Klasse in einem (benutzerdefinierten) CollectionEditor (an das Editor-Attribut gebunden) ausblenden, jedoch nicht allgemein, sondern selektiv mithilfe von Kontextinformationen.
Ich habe eine Anwendung mit zwei Editoren. Nennen wir sie Kundeneditor (CEditor) und Modelleditor (MEditor).
Wir verschaffen Ihnen mehr Kontext, in der Hoffnung, dass daraus kein Roman entsteht:
Den gibt es eine Konfiguration, die von beiden Editoren bearbeitet werden kann. Es gibt eine Eigenschaft eines Baumknotens, die früher vom CEeditor und MEditor bearbeitet werden konnte. Nennen wir diese Eigenschaft [b]Pickers[/b].
Die Bearbeitung wird dynamisch zur Verfügung gestellt mit einer Ableitung von CollectionEditor.
Die Konfiguration wird als XML serialisiert.
Die [b]Pickers[/b]-Eigenschaft ist eine Sammlung von Elementen, sie können vom Typ PickerA sein , PickerB, PickerC usw. aber alle erben von [b]PickerBase[/b] und sie teilen eine gemeinsame Eigenschaft [b]Searcher[/b], die in [b]PickerBase[/b] definiert ist.
In der Vergangenheit war das Browsable-Attribut dieser Eigenschaft auf [b]true[/b] gesetzt, was dazu führte, dass die Eigenschaft zur Bearbeitung im benutzerdefinierten [b]CollectionEditor[/b] angezeigt wurde. Beide Editoren verwendeten dasselbe Steuerelement. Nennen wir es [b]ResponsiveDesigner[/b], um eine Baumansicht zu hosten, in der bei Auswahl eines bestimmten Knotens ein Eigenschaftenraster ausgefüllt wird und wenn der Benutzer auf die [b]Auswahl[/b] klickt > Eigenschaft „…“ würde sich der benutzerdefinierte [b]CollectionEditor[/b] öffnen und dem Benutzer die Möglichkeit bieten, die Auswahl zu bearbeiten.
Jetzt möchte ich den [b]Sucher [/b] Nur Eigenschaft dieser verschiedenen Picker-Typen im CEditor sichtbar (und damit bearbeitbar) sein, nicht im MEditor.
Dazu habe ich ein neues Attribut BrowsableInEditor mit einer (BrowsableIn)-Enumeration mit den Werten erstellt:< /p>
[list]
[*]Beide
[*]CEdtiorOnly
[*]MEditorOnly
[/list]
Im Inneren Klasse [b]PickerBase[/b] Ich habe das Attribut Browsable der Eigenschaft [b]Searcher[/b] auf „false“ gesetzt und den BrowsableInEditor( hinzugefügt.[code]BrowsableIn.CEditorOnly[/code])-Attribut.
Es gab eine vorhandene Klasse:
[code]public class PickerConfigurationEditor : CollectionEditor
{
public PickerConfigurationEditor(Type type) : base(type) { }
protected override object CreateInstance(Type itemType) => base.CreateInstance(itemType);
protected override Type[] CreateNewItemTypes() =>
...
}
[/code]
Ich habe eine neue Klasse hinzugefügt, die von [b]CollectionEditor[/b] erbt und durch Überprüfung des Besitzers des Editors feststellen kann, ob sie sich im Kundeneditor- oder Modelleditormodus befindet:
[code]public abstract class ContextAwareCollectionEditor : CollectionEditor
{
private Form ParentForm { get; set; }
protected ContextAwareCollectionEditor(Type type) : base(type) { }
protected override object CreateInstance(Type itemType)
{
var instance = base.CreateInstance(itemType);
if (instance is IContextAwareTypeDescriptor list && ParentForm is {Owner: IContextAwareDesigner contextAwareDesigner})
{
list.CustomerEditorMode = contextAwareDesigner.CustomerEditorMode ;
}
return instance;
}
protected override CollectionForm CreateCollectionForm()
{
var collectionForm = base.CreateCollectionForm();
ParentForm = collectionForm.FindForm();
return collectionForm;
}
}
[/code]
Jetzt erbt der [b]PickerConfigurationEditor[/b] von diesem [b]ContextAwareCollectionEditor[/b]:
öffentliche Klasse PickerConfigurationEditor: ContextAwareCollectionEditor
{
public PickerConfigurationEditor (Typtyp): base(type) {
[code]protected override Type[] CreateNewItemTypes() =>
...
[/code]
Sehen wir uns auch an, wie der Editor zugeordnet ist:
[code][Editor("xyz.PickerConfigurationEditor , xyz.UiExtensions", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public sealed class PickersList : List
, IContextAwareTypeDescriptor
{
public bool CustomerEditorMode { get; set; }
...
public PropertyDescriptorCollection GetProperties()
{
var pds = new PropertyDescriptorCollection(null);
for (var i = 0; i < Count; i++)
{
pds.Add(new PickerBaseDescriptor(this, i, CustomerEditorMode));
}
return pds;
}
[/code]
(IContextAwareTypeDescriptor erbt von ICustomTypeDescriptor und fügt eine CustomerEditorMode-Eigenschaft hinzu)
Und der [b]PickerBaseDescriptor[/b] sieht so aus:
öffentliche versiegelte Klasse PickerBaseDescriptor: PropertyDescriptor
{
private readonly PickersList _pickersList;
private readonly int _index = -1;
private readonly bool _customerEditorMode;
[code] public PickerBaseDescriptor(PickersList list, int idx, bool customerEditorMode) :
base("#" + idx.ToString(), null)
{
_pickersList = list;
_index = idx;
_customerEditorMode= customerEditorMode;
}
public override bool IsBrowsable
{
get
{
var browsableAttr = Attributes.OfType
().FirstOrDefault();
if (browsableAttr?.Browsable == true) return true;
var editorAttr = Attributes.OfType
().FirstOrDefault();
return editorAttr?.BrowsableIn == BrowsableIn.Both || editorAttr?.BrowsableIn == BrowsableIn.KpfOnly && _customerEditorMode
|| editorAttr?.BrowsableIn == BrowsableIn.DesignerOnly && !_customerEditorMode;
}
}
public override AttributeCollection Attributes => new AttributeCollection(null);
...
[/code]
Das Problem ist, dass das nicht funktioniert. Wenn ich in der Methode [b]GetProperties[/b] von PickersList einen Haltepunkt setze, wird dieser nicht erreicht.
Die Frage ist also entweder, was mache ich falsch oder vielleicht TL ;DR: Wie kann ich eine Eigenschaft einer Klasse in einem (benutzerdefinierten) CollectionEditor (an das Editor-Attribut gebunden) ausblenden, jedoch nicht allgemein, sondern selektiv mithilfe von Kontextinformationen.