Ich habe eine Liste mit Elementen, die eine Eigenschaft vom Typ int/enum besitzen. Also vereinfacht z.B. sowas:
public enum Typen
{
Kreis= 0,
Rechteck = 1,
Dreieck = 2
}
Die Liste sieht dann so aus:
private List<Geometrie> _Geometrien;
...
public List<Geometrie> Geometrien
{
get { return _Geometrien; }
set { _Geometrien = value; RaisePropertyChangedEvent("Geometrien"); }
}
...
}
Und die zugehörige Klasse:
public class Geometrie : ObservableObject
{
private Typen _Typ;
...
public Typen Typ
{
get { return _Typ; }
set { _Typ = value; RaisePropertyChangedEvent("Typ"); }
}
...
}
Ich möchte jetzt in meiner Oberfläche diese Geometrien nebeneinander anzeigen und haben mir ein Dictionary mit passenden "Bildchen" (x:Key="KreisBild",...) als Grids angelegt. Meine Idee war das Ganze über ein ItemsControl zu machen, das eine horizontale StackPanel besitzt:
<ItemsControl ItemsSource="{Binding Geometrien}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Height="20" Width="20" Stroke="Black" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Wie bekomme ich jetzt hin, dass passend zum Typ des Objekts das entsprechend Bild eingebunden wird? Ich habe schon mit DataType im DataTemplate gearbeitet aber hier sind ja alle Objekte vom gleichen Typ und sollen anhand des Eigenschaftswertes unterschieden werden.
Hi NOFX,
du könntest dafür Trigger verwenden, siehe Abschnitt "Styles und Trigger" in [Artikel] MVVM und DataBinding
Allerdings würde es sich anbieten, die Geometry-Typen als eigene Klassen zu implementieren. Ein Kreis hat ja auch andere Eigenschaften als ein Rechteck oder ein Dreieck. Dann könntest du die Template-Zuweisung per DataType machen.
Ansonsten empfehle ich noch einen Blick in [Artikel] C#: Richtlinien für die Namensvergabe
Weeks of programming can save you hours of planning
Hat zwar nichts mit dem Thema selbst zu tun, aber PropertyChanged.Fody könnte ganz schnell dein Freund werden.
Hi MrSparkle,
danke schonmal für die schnelle Antwort!
Sowohl Namen als auch der Sinn der Klasse sind nur beispielhaft und ergeben nicht unbedingt Sinn. 😃
Eine Unterscheidung durch unterschiedliche Klassen ist nicht möglich.
D.h. der DataTrigger wäre wohl der richtige. Ich kenne den nur in Kombination mit Styles. Hier möchte ich ja das DataTemplate komplett ändern bzw. eben ein WPF-Bildchen (als Grid gekapselt) anzeigen.
D.h. ich habe eigentlich zwei Fragen, wie kriege ich überhaupt ein Grid (x:Key="KreisBild",...) aus den Resources angezeigt (wie das sonst mit Styles geht ist mir klar) und wie mache ich das in Kombination mit einem DataTrigger.
Du kannst in einem Style bzw. einem Trigger auch die Template-Eigenschaft setzen. Du könntest auch in einem Template Styles mit Trigger haben. Du kannst auch die Content-Eigenschaft per Trigger setzen, oder bestimmte Elemente im Template per Trigger ein- oder ausblenden. Es gibt viele Wege zum Ziel.
Weeks of programming can save you hours of planning
Danke für die Antwort! Ich habe die Bildchen jetzt als DataTemplates (mit dem Grid jeweils drin) angelegt und gehe über den DataTrigger im Style und ändere das ContentTemplate:
<ItemsControl ItemsSource="{Binding Geometrien}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource KreisBild}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CoolStripZoneType}" Value="1">
<Setter Property="ContentTemplate" Value="{StaticResource RechteckBild}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>