Dynamisch Include-Dateien hinzufügen (Hintergrunddateien)

Guten Abend,
ich habe alle meine Formulare in meiner Datenbank. Weiterhin gibt es Hintergrundformulare (Include-Dateien). Diese möchte ich dynamisch zur Laufzeit ins Formular einfügen. Ich habe folgenden Code probiert, aber er funktioniert nicht. Weiß jemand, warum nicht?

            // Load include files
        var hintergrundFormulare = FormularServer.GetHintergrundFormulare(pFormular.Id);

        // Set all files into the repository
        _repo.SetFiles(pFormular, hintergrundFormulare);

        try
        {
            // Create new project
            using (ProjectList proj = new ProjectList(_listLabel))
            {
                // Create new stream
                using (MemoryStream memStream = new MemoryStream())
                {
                    // Copy given formular to stream (without any include files jet)
                    memStream.Write(pFormular.Inhalt, 0, pFormular.Inhalt.Length);
                    memStream.Position = 0;

                    // Open project
                    proj.Open(memStream);

                    // Iterate through all needed include files
                    foreach (var hintergrundFormular in hintergrundFormulare)
                    {
                        if (hintergrundFormular.IstFomrularLeer)
                        {
                            continue;
                        }
                        try
                        {
                            // Create include object and set the include LLId filename, to add it to my project
                            Template include = new Template(proj.ProjectTemplates);
                            include.FileName = "\"" + hintergrundFormular.LLId + "\""; // "repository://{EFCEE0BB-79A3-497A-94EB-D9CFF9A71217}";
                        }
                        catch (System.Exception ex)
                        {
                            //_logger.Log(ex);
                        }
                    }

                    // set stream and start designer
                    _listLabel.AutoProjectStream = memStream;
                    //_listLabel.AutoProjectFile = pFormular.LLId; // LLHelper.GetRepositoryItemId(pFormular.Id);
                    _listLabel.Design();
                    //_listLabel.Design(LlProject.List, memStream);

                    // working with the project leads in exceptions (Save, Close, Dispose)
                    //proj.Save();
                    //proj.Close();

                    // Verändertes Formular wieder speichern
                    FormularServer.AddOrUpdate(pFormular);
                }
            }// <-- using Project - Exception (no access to a temp file because of another process)
        }
        catch (System.Exception ex)
        {
            System.Windows.MessageBox.Show(ex.Message);
        }

Ich würde einmal probieren, das Projekt nach Hinzufügen der Templates zu Speichern und zu Schließen. Anschließend dann den Stream noch einmal neu abrufen bzw. - besser - für AutoProjectFile direkt die Repository-URL übergeben. Dann kümmert sich LL automatisch um die Stream-Verwaltung. Das sollte auch schon beim Open des Projekts klappen.

Danke für die Antwort. Das speichern und schließen des Projektes nach dem Hinzufügen der Templates hat erstmal geklappt. Aber wie kann ich AutoProjectFile die Repo-Url übergeben? Mein Repository implementiert ja IRepository, dort gibt es kein GetUrl oder sowas?

1 Like

Sie können die GetAllItems-Methode aufrufen, damit erhalten Sie alle RepositoryItems. Diese enthalten jeweils eine InternalID, die Sie über den gleichnamigen Getter abfragen können.

Guten Abend,

leider funktioniert das noch nicht so ganz. Ich möchte gern die Hintergrunddateien dynamisch hinzufügen, ohne sie auf dem Dateisystem zu speichern. Ich weise dem Template als Dateiname die InternalId zu (sowas wie “repository\{GUID}”). Ich sehe in meinem eigenen Repository auch, wie GetItems und GetItem mit genau dieser Id aufgerufen wird, aber im Designer kommt eine Fehlermeldung, “Fehler beim Laden des Projektbausteins”, “Der Baustein ‘repository://{GUID}’ wurde nicht gefunden. Es fehlen Ihnen vermutlich nun Objekte…”. Was genau mache ich noch falsch? Gibt es dazu irgendwo ein fertiges Beispiel? (Template-Dateien hinzufügen ohne Dateisystem)?

Können Sie hier einmal eine Logdatei posten, die genau diesen Vorgang zeigt? Ansonsten kann ich mir das morgen im Büro gerne einmal genauer ansehen.

Ich habe mir das wie versprochen angesehen. Ich hänge Ihnen einmal ein Spielprojekt hier an. Bitte sehen Sie mir das grausame Design nach - es ist ein ausgebeintes, internes Testprojekt bei dem Schönheit keine Rolle gespielt hat :wink:. Die Form hat drei relevante Schaltflächen:

“import files” -> damit werden zwei Testdateien (Base.lst, LogoTemplate.lst) in das Repository aufgenommen. Im Beispiel ist dies eine Repository-Implementierung, die im Temp-Verzeichnis einen eigenen Folder aufmacht. Hier müssten Sie stattdessen Ihr Repository übernehmen. Beim Import werden auch gleich die beiden URLs in rootId und templateId gemerkt. Das sieht so aus:

using (var LL = new ListLabel(LlLanguage.Default))
{
    using (var importUtil = new RepositoryImportUtil(CurrentRepository))
    {
        rootId = importUtil.ImportProjectFile(LL, Path.GetFullPath("Base.lst"), "RootProject", null, null);
        templateId = importUtil.ImportProjectFile(LL, Path.GetFullPath("LogoTemplate.lst"), "Template", null, null);
    }
}
btnRefreshRepoList.PerformClick();

“Clear Repository” -> löscht das Repository für einen neuen Testdurchlauf

“Open Designer” -> fügt per DOM den Baustein “LogoTemplate” zum “Base”-Projekt hinzu und öffnet dann den Designer

Der Code hinter “Open Designer” ist recht simpel:

var prov = new ObjectDataProvider(new List<string>());

using (var ll = new ListLabel())
{
    ll.FileRepository = CurrentRepository;
    ll.DataSource = prov;
    ll.AutoProjectType = LlProject.List;

    using (ProjectList proj = new ProjectList(ll))
    {
        proj.Open(rootId, LlDomFileMode.Open);
        Template template = proj.ProjectTemplates.AddNew();
        // Die Anführungszeichen hier sind wichtig, das Ergebnis muss eine Formel sein!
        template.FileName = "'"+templateId+"'"; 
        proj.Save();
        proj.Close();
    }
    ll.Design(null, this.Handle, "Designer", LlProject.List, rootId, false);
}

Vielleicht können Sie so das Problem in Ihrer eigenen Implementierung finden?
RepositoryTest.zip (21.6 KB)

Hallo Herr Bartlau,

so, nun habe ichs. Es geht, danke sehr. Das Hauptproblem war nun nur noch, dass ich beim Laden eines Projektes ggf. bereits gesetzte Templates auch weider entfernen muss. Deswegen hat er sie nicht gefunden (Templates waren nicht im Repo, aber noch in der Datei). Nun geht es problemlos - übrigens auch mit dem Code, den ich bereits vor 3 Tagen gepostet hatte. Hoffentlich hilft er auch anderen LL-Nutzern.

Viele Grüße aus Berlin.

1 Like