+1 800 256 3608 (toll-free in North America) or +49 7531 90 60 10| service@combit.com

Problem bei der Felder-Übersicht von Collections im Designer


(Simone Lange) #1

Hallo,

wenn ich meinem ListLabel Objekt über LL.SetDataBinding(enumerable, string.Empty) eine Datenquelle zuweise, habe ich ein Problem bei der Übersicht der Felder rechts im Designer.

Habe ich z.B. als Ausgangslage diese Klassenstruktur:

[code]public class All
{
public PersonTypeOne PersonOne { get; }
public PersonTypeTwo PersonTwo { get; }
}

public class PersonTypeOne
{
public ICollection Addresses { get; }
public string Name { get; }
}

public class PersonTypeTwo
{
public ICollection Addresses { get; }
public int Id { get; }
}

public class Address
{
public int PostalCode { get; }
public string Region { get; }
}
[/code]

Die Übersicht rechts der Felder sieht dann so aus (> steht für Ordner):

[code]> PersonTypeOne
Name

PersonTypeTwo
Id

Addresses
PostalCode
Region

PersonTypeTwoAddresses
PostalCode
Region
[/code]
Da aber die Collection auch eine Eigenschaft der PersonTypeOne bzw. PersonTypeTwo ist, möchte ich folgende Struktur haben:

[code]> All

PersonTypeOne
Name
Addresses
PostalCode
Region

PersonTypeTwo
Id
Addresses
PostalCode
Region
[/code]
Die Übersicht der Felder rechts stimmt also nicht mit der Hierarchie der Klassen in der Datenquelle überein.

Probiert habe ich, über die AutoDefineElementEventArgs des AutoDefineField-Events den Namen anzupassen, aber der ursprüngliche Typ wird soweit ich weiß nicht mit übergeben, wobei der Designer die richtige Hierarchie kennt, da er die zweite Collection Addresses mit dem Präfix der “PersonTypeTwo” benennt (was leider auch dazu führt, dass die Übersetzungen für diesen Ordner im ListLabelDictionary nicht mehr erkannt werden), falls die Collection der “PersonTypeOne” zuerst angemeldet wurde.
Außerdem ist beim Anlegen der Tabellen und Untertabellen im Berichtscontainer die richtige Hierarchie zu erkennen.

Warum werden die ICollections dann nicht auch direkt mit PersonTypeOne.Addresses (bzw. PersonTypeTwo.Addresses) angemeldet, wie die anderen Eigenschaften?

Dann habe ich noch den Hinweis aus dem Thread (Geschachtelte DataSource) LL.DataSource = new ObjectDataProvider(enumerable) { FlattenStructure = true }; probiert, was leider auch nicht die gewünschte Übersicht erzeugt.
Mit der Eigenschft “RootTableName=All” konnte ich aber wenigstens “PersonTypeOne” und “PersonTypeTwo” einem gemeinsamen Element unterordnen, die “Addresses” Collections befinden sich dann auf einer Ebene mit “All”

Wie kann ich das gewünschte Resultat erzielen, ohne aufwendig jedes Feld selber anzumelden?

Programmiert wird in C#/WPF mit der List&Label Version 22.

Viele Grüße,
Simone


(combit Support - Christian Rauchfuß) #2

Hallo Frau Lange,

vielen Dank für Ihren Beitrag.

Der Feld-/Variablen-Tree zeigt nicht die wirkliche Feldstruktur. Diese sehen Sie, wenn Sie innerhalb des Berichtscontainers eine neue Tabelle einfügen. Bei der Auswahl der Datenquelle sollte dann die Berichtsstruktur stimmen.

Mit freundlichen Grüßen

Christian Rauchfuß
Technischer Support
combit GmbH


(Simone Lange) #3

Hallo Herr Rauchfuß,

vielen Dank für Ihre Rückmeldung.

Dass der Feld-/Variablen-Tree nicht die wirkliche Feldstruktur zeigt und dass bei der Auswahl der Datenquelle die Berichtsstruktur stimmt, hatte ich ja bereits selber festgestellt (und auch in meinem Beitrag oben so beschrieben).

Meine Frage war eher, warum das so ist und wie ich die Übersicht so hinbekomme, dass sie der Auswahl der Datenquelle der Berichtsstruktur entspricht?
Wäre das nicht eigentlich das gewünschte Verhalten, dass der Feld-/Variablen-Tree die wirkliche Feldstruktur anzeigt?

Mit freundlichen Grüßen,
Simone Lange


(combit Support - Christian Rauchfuß) #4

Hallo Frau Lange,

Jede Tabelle kann - je nach Datenquelle - auch auf Top-Level-Ebene erscheinen. Insofern handelt es sich bei den verschiedenen Darstellungen um zwei Paar Schuhe, das eine ist “welche Tabelle habe ich und wie sehen die Felder darin aus” (Feld-/Variablenliste auf der rechten Seite), das andere ist “wie sieht die Berichtsstruktur aus” (Auswahl der Datenquelle für ein Berichtscontainerobjekt).

Mit freundlichen Grüßen

Christian Rauchfuß
Technischer Support
combit GmbH


(Simone Lange) #5

Hallo Herr Rauchfuß,

vielen Dank noch einmal für Ihre Antwort. Leider sehe ich da immer noch zwei Probleme. Um das zu verdeutlichen habe ich ein kleines Beispiel und unter meinem Beitrag einen Nachbau der Felderübersicht erstellt, da ich keinen Screenshot aus dem Designer der Felderübersicht angehängen darf.
Die Übersicht zeigt mir so zwar an, welche Tabellen ich haben könnte, aber nicht wie die Felder darin aussehen, da die Adressen auch jeweils Teil der einzelnen Personen sind.
Wenn ich über den Zusammenhang der Daten nichts weiß, müsste ich außerdem raten, zu wem denn nun die Noten, Geräte, Raumnummern und Fächer gehören. Zudem werden nur der Schulleiter und der Hausmeister unter dem RootTablename Schule zusammengefasst und nicht die Collections Schüler und Lehrer.
Da die Übersicht im Berichtscontainer aber die richtige Ansicht zeigt, ist das das kleinere Problem.
Problematischer finde ich dabei die Lokalisierung. Für die erste Klasse, die von PersonBase erbt, wird Addresses noch korrekt übersetzt, alle weiteren bekommen dann ihren Klassennamen als Präfix.
Dann müsste ich für jede Collection auch noch eine zusammengesetzte Übersetzung bereitstellen und zudem wissen, wessen Adressen mit “Feldnamen” als erstes angemeldet werden (und hoffen, dass die Reihenfolge immer gleich ist und die Reihenfolge der Felder innerhalb der Klasse nie geändert werden). Da die anderen Felder einer Klasse mit “Klassennamen.Feldnamen” angemeldet werden, verstehe ich nicht, warum man hier auf die Eindeutigkeit verzichtet und stattdessen erst beim zweiten Auftreten eines Feldes “KlassennamenFeldnamen” ohne Punkt verwendet.

Hoffentlich wurde mein Einwand nun klarer.
Mit freundlichen Grüßen,
Simone Lange

PS. nachfolgend der Nachbau der Felderübersicht, die ich im Designer bekomme,

> Adressen
    > Land
    Adresszusatz
    Anschrift
    Label
    Name
    Ort
    Postleitzahl
    Region
> Fächer
    Wert
> Geräte
    Wert
> Hausmeister
    Vorname
> JanitorAddresses
    > Land
    ...
> Lehrer
    Vorname
> Noten
    Wert
> PupilsAddresses
    > Land
    ...
> Raumnummern
    Wert
> Schule
    > Hausmeister
        Vorname
    > Schulleiter
        Vorname
> Schüler
    Vorname
> TeachersAddresses
    > Land
    ...

der Aufbau der einzelnen Klassen,

[code]
class School
{
public Headmaster Head { get; set; } = new Headmaster();
public Janitor Janitor { get; set; } = new Janitor();
public ObservableCollection Pupils { get; } = new ObservableCollection();
public ObservableCollection Teachers { get; } = new ObservableCollection();
}

class Headmaster : PersonBase
{
    public ObservableCollection<int> RoomNumbers { get; set; } = new ObservableCollection<int>();
}

class Janitor : PersonBase
{
    public ObservableCollection<string> Equipment { get; } = new ObservableCollection<string>();
}

class Pupil : PersonBase
{
    public ObservableCollection<int> Grades { get; set; } = new ObservableCollection<int>();
}

class Teacher : PersonBase
{
    public ObservableCollection<string> Subjects { get; } = new ObservableCollection<string>();
}

class PersonBase
{
    public ObservableCollection<Address> Addresses { get; set; }
    public string GivenName { get; set; }
}

public class Address 
{
    public string Label { get; set; }
    public string Name { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string PostalCode { get; set; } 
    public string Region { get; set; }
    public Country Country { get; set; }
}[/code]

die Zuweisung der Datenquelle und wie die Einträge des Dictionaries angelegt werden:

[code]listLabelObject.DataSource = new ObjectDataProvider(new List() { new School() }) { FlattenStructure = true, RootTableName = “Schule” };

listLabelObject.Dictionary.Tables.Add(“School”, “Schule”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Janitor”, “Hausmeister”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Schule.Janitor”, “Schule.Hausmeister”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Head”, “Schulleiter”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Schule.Head”, “Schule.Schulleiter”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Pupil”, “Schüler”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Pupils”, “Schüler”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Teacher”, “Lehrer”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Teachers”, “Lehrer”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Addresses”, “Adressen”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Grades”, “Noten”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Equipment”, “Geräte”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“RoomNumbers”, “Raumnummern”, currentCultureId);
listLabelObject.Dictionary.Tables.Add(“Subjects”, “Fächer”, currentCultureId);
listLabelObject.Dictionary.Identifiers.Add(“GivenName”, “Vorname”, currentCultureId);
listLabelObject.Dictionary.Identifiers.Add(“Address1”, “Anschrift”, currentCultureId);
listLabelObject.Dictionary.Identifiers.Add(“Address2”, “Adresszusatz”, currentCultureId);
listLabelObject.Dictionary.Identifiers.Add(“City”, “Ort”, currentCultureId);
listLabelObject.Dictionary.Identifiers.Add(“PostalCode”, “Postleitzahl”, currentCultureId);[/code]


(combit Support - Christian Rauchfuß) #6

Hallo Frau Lange,

vielen Dank für Ihren Beitrag.

Ihre Erläuterung ist korrekt. Aktuell gibt es jedoch keine andere Möglichkeit als die Verwendung zusammengesetzter Aliase.

Mit freundlichen Grüßen

Christian Rauchfuß
Technischer Support
combit GmbH