XAML MergedDictionaries Ressourcen heben sich gegenseitig auf

AnnaBauer21

Grünschnabel
Hallo ihr Lieben,

ich stehe vor einem Problem und finde einfach keine Lösung dafür.
Meine Kollegen konnten mir auch nicht weiterhelfen.

Es gibt im Projekt eine XAML, in der alle Ressourcen der selbst erstellten GUI-Elemente eingetragen werden.
XML:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <ResourceDictionary.MergedDictionaries>
        ...
        <ResourceDictionary Source="pack://application:,,,/Test.Gui;Component/Fields/ExtraDataGridExtendResources.xaml" />
        <ResourceDictionary Source="pack://application:,,,/Test.Gui;Component/Fields/ExtraDataGridExtendRotateResources.xaml" />
        ...
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Beide oben genannten Elemente leiten von DataGrid ab.
Der Style wird im static Konstruktor entsprechend geladen.
C#:
/// <summary>
/// Statischer Konstruktor zum Laden des StandardStyles
/// </summary>
static ExtraDataGridExtendRotate()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(ExtraDataGridExtendRotate), new FrameworkPropertyMetadata(typeof(ExtraDataGridExtendRotate)));
}
In den Resources.xaml sind dann alle Styles definiert, ich habe bei den beiden oben genannten jedem Style einen eindeutigen x:Key gegeben, damit sich diese laut meinem Kollegen nicht gegenseitig aufgeben.
Am Ende der Resources.xaml stehen die folgenden Einträge:
XML:
<Style BasedOn="{StaticResource BaseExtraDataGridExtendRotateStyle}" TargetType="{x:Type localTest:ExtraDataGridExtendRotate}" />
<Style BasedOn="{StaticResource HeaderExtraDataGridExtendRotateStyle}" TargetType="{x:Type DataGridColumnHeader}" />
Die 2. Zeile weist dem DataGridColumnHeader den entsprechenden Style zu. Da dies in beiden Resources.xaml gemacht wird, könnte dies das Problem sein, warum der Header in ExtraDataGridExtend nun genau so aussieht wie in ExtraDataGridExtendRotate.

Zum Test habe ich eine eigene Header Klasse erstellt und von DataGridColumnHeader abgeleitet.
C#:
public class MyDataGridColumnHeader : DataGridColumnHeader
{
    static MyDataGridColumnHeader()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyDataGridColumnHeader), new FrameworkPropertyMetadata(typeof(MyDataGridColumnHeader)));
    }
}
In einem der beiden oben genannten Resources.xaml habe ich nun am Ende bei dem entsprechenden Eintrag meine Klasse angegeben, damit ich 2 verschiedene Header-Klassen habe und jedem ein entsprechender Style zugewiesen werden kann.
1. Resource.xaml (ExtraDataGridExtend / DataGridColumnHeader)
XML:
<Style BasedOn="{StaticResource BaseExtraDataGridExtendStyle}" TargetType="{x:Type localTest:ExtraDataGridExtend}" />
<Style BasedOn="{StaticResource HeaderExtraDataGridExtendStyle}" TargetType="{x:Type DataGridColumnHeader}" />
2. Resource.xaml (ExtraDataGridExtendRotate / localTest:MyDataGridColumnHeader)
XML:
<Style BasedOn="{StaticResource BaseExtraDataGridExtendRotateStyle}" TargetType="{x:Type localTest:ExtraDataGridExtendRotate}" />
<Style BasedOn="{StaticResource HeaderExtraDataGridExtendRotateStyle}" TargetType="{x:Type localTest:MyDataGridColumnHeader}" />
Im 2. Resources.xaml habe ich überall (Styles & Templates) DataGridColumnHeader durch MyDataGridColumnHeader ersetzt.
An einer Stelle (PART_FillerColumnHeader) habe ich gesehen, dass es funktioniert hat.
XML:
<Style x:Key="TestHeader" TargetType="{x:Type DataGridColumnHeadersPresenter}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
                <Grid
                    x:Name="PART_DataGridColumnHeadersPresenter"
                    HorizontalAlignment="Stretch"
                    Background="BlueViolet">
                    
                    <localTest:MyDataGridColumnHeader
                        x:Name="PART_FillerColumnHeader"
                        Background="Aqua"
                        Visibility="Visible" />
                        
                    <ItemsPresenter x:Name="PART_Items" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Das Problem das aber weiterhin besteht ist der ItemsPresenter.
Ich habe im oben genannten Code-Stück keine Möglichkeit dem ItemsPresenter zu sagen, welchen Typ seine Items haben sollen.
In "Snoop" (siehe Bild) sehe ich, dass dort immer noch der falsche DataGridColumnHeader verwendet wird.

Ich hoffe ihr könnt mir bei meinem Problem weiterhelfen.
Vielen Dank schonmal für eure Mühe.

Liebe Grüße
Anna
 

Anhänge

  • Snoop3.png
    Snoop3.png
    13,4 KB · Aufrufe: 2
einen eigenen abgeleiteten DataGridColumnHeader ist meines Wissens nicht so einfach und das anlegen wirst du wohl eher auf C# Seite machen müsste.

Aber andere frage, was hast du genau vor das man das nicht auch über HeaderTemplate und/oder AttachedProperties lösen könnte, brauchst du wirklich eine Ableitung?
 
Hallo,

die Ableitung war eine Idee um das Problem in den MergedDictionaries zu umgehen.

Sprich es gibt 2 Klassen die von DataGrid ableiten.
Jede Klasse hat sein eigenes Resourcen.XAML in denen bei beiden Angaben zum z.B. HeaderStyle gemacht werden.

Da in dem Projekt aber alles in eine gemeinsame Datei, in der nur dieses MergedDictionaries beinhaltet ist, reingeladen wird, wird der HeaderStyle der einen Klasse mit dem HeaderStyle der anderen überschrieben, da quasi 2 mal eine Definition zum HeaderStyle in den MergedDictionaries vorhanden sind.
Der Eintrag in MergedDictionaries gewinnt sozusagen.

Leider hat die Ableitung aber nun dazu geführt, dass der ItemsPresenter die neue Klasse nicht kennt.

Ich freue mich natürlich über jede andere Lösung, nur müsste diese irgendwie mit dem vorhandenen Konzept zu lösen sein.
 
Ansosnten hat dein Kollege schon recht mit x:key werden die Styles entsprechend nur dort verwendet wo entsprechend die Ressource laut Key verlangt wird.

ich glaube dein Problem ist diese angabe
Code:
<Style BasedOn="{StaticResource HeaderExtraDataGridExtendRotateStyle}" TargetType="{x:Type DataGridColumnHeader}" />
dort gibt es kein x:Key und damit gilt es erstmal für alle DataGridColumnHeader die nicht auf eine bestimmte Key Ressource verweisen.

Nachtrag:
Vielleicht hilft dir ja der DataGridColumnHeadersPresenter, hab den aber selbst auch noch nicht verwendet.
Quasi ein Grid drüber, im Grid die Rotation festlegen und dann den Presenter aufrufen, mal so billige vermutung das ev. funktionieren könnt.
 
Zuletzt bearbeitet:
Zurück