Sorry für die späte Antwort. Ich bin grad am grübeln, ob ich das Thema irgendwie ohne dieses Treeview lösen kann. Bin damit nicht wirklich zufrieden 😦 Das scheint sehr komplex zu sein...
Zitat von Th69
Was soll denn der ausgewählte Datensatz bei der ComboBox genau sein (außer dem gewählten
CodeArea
-Objekt)?
Letzendlich soll der DamageCode ausgewählt sein. Den brauch ich dann zur weiteren Verarbeitung.
Du kannst zwar im TreeView einzelne Items (Zeilen) markieren, für die Anzeige in der ComboBox wird aber als
SelectedItem
immer nur ein Element der zugewiesenenItemsSource
ausgewählt (bei dir also einCodeArea
- Objekt).
Stimmt, daran hab ich gar nicht gedacht. Das SelectedItem
ist ja nur das von der Combobox und nicht vom TreeView. Und da ist es die CodeArea
.
Du müßtest ansonsten noch eine weitere Eigenschaft
SelectedEntry
(o.ä). erstellen und diese dann per Binding an das TreeView.SelectedItem aktualisieren lassen.
Geht das denn überhaupt? Ich hab ja letzendlich für jedes Item der Combobox ein eigenes TreeView. Ich versuch mal mein Glück.
Aber was soll in der ComboBox angezeigt werden, wenn eine der übergeordneten Elemente (wie z.B. "QSVS Zuordnung" oder "Umwelteinflüsse") markiert wird?
Das wäre die nächste Frage. Die sollen eigentlich nicht gewählt werden können 😃
Hinweis: Deine Modelle sind wohl Datenbank Entitäten, weil sie ICollection verwenden, so wäre die korrekte Initialisierung ein HashSet und keine List.
Relationen zwischen Entitäten können nur ein mal existieren, weshalb EFCore unter der Haube auch HashSet verwendet. HashSet ist für solche Use Cases konzipiert und optimiert; List macht kein Sinn.PS: wenn es Entitäten sind, dann solltest das vielleicht auch so benennen 😃
Hab es an meinen Kollegen weitergegebn 😃 Danke
Hab das ControlTemplate separiert, danke 😃
Das ist die Voreinstellung wenn weder
DisplayMemberPath
gesetzt ist noch dieToString
-Methode überschrieben wurde
Aber wenn man das ItemTemplate setzt mit einem Textblock zb. und dann die Text Eigenschaft bindet, wird doch dieses Binding übernommen für den angezeigten Wert?
es werden ja nur die Daten im Model neu zugewiesen, der Code bleibt ja derselbe)
Das muss ich mal probieren. Ich war der Meinung die komplette Model-Klasse wird erneuert
Das versteh ich nicht, denn dieser
TextBlock
ist doch in jedemTreeView
-Item enthalten, d.h. du hast eine (hierarchische) Liste davon. Willst du dann alle anzeigen oder nur den ersten Eintrag davon?
Ich meine das selektierte Element soll in der Struktur angezeigt werden: Id - CodeDescription
ComboBox mit TreeView-Elementen? Das habe ich bisher noch nicht gesehen
War für meinen Fall ganz praktisch. Ich nehme aber gerne auch andere Ideen auf. Im Anhang mal ein Bild wie es aussieht 😃 In diesem Fall sollte in der Combobox oben "1001 - Umwelteinflüsse" stehen.
PS: Hattest du meine letzte Antwort aus deinem Beitrag ListView zeigt nur Objektnamen an, Problem mit ContentPresenter und DataTemplates noch gelesen? Oder hast du inzwischen eine andere Lösung (außer der Codeduplikation) gefunden?
Ne hatte ich noch nicht gesehen. Hab es bisher bis Codeduplikation gelöst. Muss ich mir dann nochmal anschauen 😃 Danke dir für dne Hinweis.
Hallo zusammen,
wiedermal ein kleines Problem:
Ich hab mir eine Combobox gebaut mit einem TreeView drin. In der TreeView hab ich einige Bindings an den Textblöcken. Die Combobox weiß nun vermutlich nicht, welches Binding als SelectedItem angezeigt werden soll und zeigt mir nur den Klassennamen an. Hier meine Combobox:
<ComboBox HorizontalContentAlignment="Stretch" ItemsSource="{Binding GlobalInstance.DropdownDamageArea}" SelectedValuePath="Name" ItemContainerStyle="{StaticResource treeCombobox}" ScrollViewer.CanContentScroll="False">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}"/>
<TreeView x:Name="tree" Margin="5" ItemsSource="{Binding CodeGroups}" Style="{StaticResource comboTreeView}">
<TreeView.Template>
<ControlTemplate>
<ItemsPresenter/>
</ControlTemplate>
</TreeView.Template>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding DamageCodes}">
<TextBlock Text="{Binding Name}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="text">
<Run Text="{Binding Id}"/>
<Run Text=" - "/>
<Run Text="{Binding CodeDescription}"/>
</TextBlock>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Dazu gehört folgender Code:
private ObservableCollection<CodeArea> dropdownDamageArea;
public ObservableCollection<CodeArea> DropdownDamageArea
{
get
{
return dropdownDamageArea;
}
set { dropdownDamageArea = value; OnPropertyChanged(); }
}
public partial class CodeArea
{
[Key]
public int Id { get; set; }
[StringLength(50)]
public string? Name { get; set; }
[InverseProperty("GroupArea")]
public virtual ICollection<CodeGroup> CodeGroups { get; set; } = new List<CodeGroup>();
}
public partial class CodeGroup
{
[Key]
public int Id { get; set; }
[StringLength(50)]
public string? Name { get; set; }
public int? GroupAreaId { get; set; }
[InverseProperty("CodeGroup")]
public virtual ICollection<DamageCode> DamageCodes { get; set; } = new List<DamageCode>();
[ForeignKey("GroupAreaId")]
[InverseProperty("CodeGroups")]
public virtual CodeArea? GroupArea { get; set; }
}
public partial class DamageCode
{
[Key]
[StringLength(4)]
[Unicode(false)]
public string Id { get; set; } = null!;
public int CodeGroupId { get; set; }
[StringLength(50)]
public string? CodeDescription { get; set; }
[ForeignKey("CodeGroupId")]
[InverseProperty("DamageCodes")]
public virtual CodeGroup CodeGroup { get; set; } = null!;
[InverseProperty("DamageCode")]
public virtual ICollection<WorkActionsHardware> WorkActionsHardwareDamageCodes { get; set; } = new List<WorkActionsHardware>();
[InverseProperty("ProcessCode")]
public virtual ICollection<WorkActionsHardware> WorkActionsHardwareProcessCodes { get; set; } = new List<WorkActionsHardware>();
}
Ich würde gerne diesen Textblock als SelectedItem in der Combobox anzeigen:
<TextBlock x:Name="text">
<Run Text="{Binding Id}"/>
<Run Text=" - "/>
<Run Text="{Binding CodeDescription}"/>
</TextBlock>
Es wird mir aber nur folgendes angezeigt (Siehe Anhang)
Zur Info: Wir arbeiten mit dem EntityFramework.
DisplayMemberPath
geht ja leider nicht, da das ItemTemplate gesetzt wird in der Combobox. Und die ToString()
- Methode überschreiben geht glaub ich auch nicht. Dies müsste ja im Model gemacht werden. Aber bei DB Änderungen wird ja jedesmal vom EF das Model überschrieben. Deshalb ist das glaub ich auch keine Lösung.
Ich hoffe Ihr habt noch Ideen
Ja aber der Code steht in einer anderen Datei. Und ja die Foreground Eigenschaft muss geändert werden.
Ich versuch es jetzt mal mit einem UserControl. Damit sollte es dann eigentlich klappen.
Aber ich hab das ControlTemplate in einer extra Style Datei. Die kennt das PackIcon direkt ja gar nicht. Dafür ist ja der ContentPresenter dachte ich..
Hey zusammen,
hab mal wieder eine kleine Frage, die Ihr sicher schnell beantworten könnt.
Ich habe einen Style für einen ToggleButton angelegt. Darin ist ein ControlTemplate mit ControlTemplate.Triggers.
Nun möchte ich einen ToggleButton erstellen, welcher ein Icon enthält. Ich nutze für Icons die mahApp Icons.
<ToggleButton x:Name="tglButton" HorizontalAlignment="Right" Background="Transparent" Width="35">
<iconPacks:PackIconMaterial Kind="Glasses" Foreground="{StaticResource yellow}" Width="20"/>
</ToggleButton>
Dieses Icon hat standardmäßig eine gelbe Farbe.
Nun möchte ich in meinem ControlTemplate.Triggers
die Farbe abhängig vom CheckState ändern.
Leider funktioniert der Trick mit TextBlock.Foreground
oder auch Control.Foreground
nur bei dem Content des ToggleButton selber. Aber nicht bei meinem Icon, welches innerhalb des ToggleButton liegt.
Mein ControlTemplate sieht wie folgend aus:
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true" CornerRadius="{Binding Source={StaticResource controlCorners}}">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Checked.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Checked.Border}"/>
<Setter Property="TextBlock.Foreground" TargetName="contentPresenter" Value="{StaticResource black}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Könnt Ihr mir hier weiterhelfen?
Liebe Grüße und danke schonmal 😃
Danke euch.
Ich hab jetzt zwei identische Styles angelegt. Der eine mit x:Key="GridViewRow"
welcher dann den GridViewRowPresenter
enthält. Und der Default-Style enthält dann den ContentPresenter
Schade, aber immerhion gibt es einen Workaround 😄
Ist nur etwas blöd, das ich jetzt an zwei Stellen den Style ändern muss 😦