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?
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.
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)?
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 . 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)
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.