Laden...

Silverlight: Custom Control erstellen

Erstellt von Xeres vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.591 Views
X
Xeres Themenstarter:in
16 Beiträge seit 2003
vor 12 Jahren
Silverlight: Custom Control erstellen

Hallo,

ich möchte ein eigenes Control erstellen, das folgende Eigenschaften besitzt:

  • Es soll eine Liste weiterer Controls beinhalten und anzeigen
  • Es sollen nur bestimmte andere Controls als "Children" eingefügt werden können
  • Das ganze soll auch beim editieren per XAML korrekt vorgeschlagen werden (d.h. per IntelliSense sollen nur die Klassen eingefügt werden, die von einer bestimmten Klasse abgeleitet sind)

Zuerst habe ich mein Control von "ItemsControl" ableiten lassen.
Damit hatte ich natürlich bereits die Möglichkeit über "Items" weitere Controls hinzu zu fügen, allerdings habe ich keine Möglichkeit gefunden die Auswahl der möglichen Komponenten / Klassen einzuschränken.

Danach habe ich mein Control von "Control" ableiten lassen und eine eigene Item-Liste implementiert. Diese Item-Liste ist aktuell von Typ "ObservableCollection<myListControlItem>".
Das hatte nun zu dem Effekt geführt, dass ich per IntelliSense im XAML-Code auch nur Controls hinzufügen konnte, die von "myListControlItem" abgeleitet sind. Wunderbar...
Nur werden diese Controls nicht gezeichnet / angezeigt. Logisch... habe das auch nirgends implemeniert. Nur hier bin ich momentan überfragt: Was / wo muss ich ansetzen um die Items meiner eigenen Liste anzuzeigen?

Zum besseren Verständnis hier mal ein paar Zeilen Code zu meinem bisherigen Ansatz:


    public class myListControl : Control
    {
        private myListControlColl _myItems { get; set; }

        public myListControlColl myItems
        {
            get
            {
                return _myItems;
            }
        }

        public myListControl()
            : base()
        {
            _myItems = new myListControlColl();
            this.DefaultStyleKey = typeof(myListControl);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();	
        }
    }


    public class myListControlColl : ObservableCollection<myListControlItem>
    {
    }


    public class myListControlItem : Button
    {
    }


        <local:myListControl>
            <local:myListControl.myListControlColl>
                <local:myListControlItem/>
            </local:myListControl.myListControlColl>
        </local:myListControl>

Vielen Dank im Voraus!

Gruß

5.742 Beiträge seit 2007
vor 12 Jahren

Ein ItemsControl scheint mir durchaus das passende Control für deinen Anwendungsfall.

Es sollen nur bestimmte andere Controls als "Children" eingefügt werden können

Standardverhalten der WPF ist hier, dass man alles als Children zulässt.

Du hast allerdings die Möglichkeit, über GetContainerForItemOverride und IsItemItsOwnContainerOverride benutzerdefinierte Container für manche Items einzufügen.
So in etwa macht das z.B. auch der TreeView, um letztlich nur TreeViewItems als (Visual-)Children zu haben, auch wenn man im Markup beliebigen Inhalt reinpacken kann.

Insgesamt ist das ein sehr mächtiges Konzept - versuche mal, ob du dein Vorhaben auf diese Weise realisieren kannst.

X
Xeres Themenstarter:in
16 Beiträge seit 2003
vor 12 Jahren

Hallo winSharp93,

danke für deine schnelle Antwort.
Ich bin mir nicht sicher, ob sich hier WPF anderst als Silverlight verhält, aber ich kann dein Beispiel mit TreeView nicht ganz bestätigen.

Hier habe ich (unter Silverlight) die Möglichkeit folgendes per XAML zu definieren:


				<sdk:TreeView>
					<sdk:TreeView.Items>
						<sdk:TreeViewItem/>
						<Button/>
						<sdk:TreeViewItem/>
					</sdk:TreeView.Items>
				</sdk:TreeView>

Und der Witz an der Sache: Der Button wird auch angezeigt.

D.h. ich kann beliebigen Inhalt platzieren. Und genau das ist es, was ich gerne vermeiden würde.
Bei Telerik habe ich bereits gesehen, dass dies auch möglich ist. Ich konnte nur nicht erkennen, wie sie das gelöst haben.

Ich weiß lediglich, dass Telerik in dem genannten Fall auf Control und nicht ItemsControl gesetzt hat.

Hast du vielleicht eine Antwort auf die Frage meines ersten Posts? Irgendwie muss es ja möglich sein die Items einer eigene Liste zu zeichnen / anzuzeigen.

5.742 Beiträge seit 2007
vor 12 Jahren

Und der Witz an der Sache: Der Button wird auch angezeigt.

Ja, aber nicht direkt: Stattdessen wird ein TreeViewItem erzeugt, das den Button enthält.
Somit "enthält" das TreeView nur TreeViewItems (auch wenn man anderes im Markup platzieren kann).

Um das wirklich so zu machen, dass man nicht von ItemsControl erbt, muss man - wie du ja schon ansatzweise richtig gemacht hast - eine eigene Collection schreiben und das eigene Control um eine Dependency Property mit deren Typ erweitern.
Du hast in deinem Beispiel nur eine "normale" Property, was Probleme mit Bindings und in XAML geben wird.

Zur Darstellung arbeitest du am besten mit Templates (als Vorlage ein CustomControl zum Projekt hinzufügen): Erstelle ein ControlTemplate für dein Control, in dem du per TemplateBinding (bzw. Binding mit RelativeSource=Self) auf diese Collection zugreifst.
Zur Anzeige der Items eignet sich hier dann z.B. ein ItemsControl (bzw. ListBox, wenn's ItemsControl in SL nicht direkt gibt).