Fix Platzhalter Editer im TemplateDesigner
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
2026-08-30 22:30:26 +02:00
parent 6468596bf3
commit 9f28081931
5 changed files with 94 additions and 17 deletions
@@ -60,6 +60,8 @@ public partial class DesignerViewModel : ObservableObject
public ObservableCollection<DesignerAsset> AssetItems { get; } = [];
public ObservableCollection<StarterTemplateItem> StarterTemplates { get; } = [];
public DesignerViewModel() => SelectedPlaceholder = Placeholders.FirstOrDefault();
public void Reset()
{
TemplateId = "neue-vorlage"; TemplateName = "Neue Vorlage"; Description = "";
@@ -83,7 +85,7 @@ public partial class DesignerViewModel : ObservableObject
Id = TemplateId.Trim(), Name = TemplateName.Trim(), Description = Description.Trim(),
PageSize = new((float)PageWidth, (float)PageHeight, Unit), LayoutFile = "layout.tpl",
Metadata = BuildMetadata(),
Placeholders = Placeholders.Select(x => new PlaceholderDefinition(x.Name.Trim(), x.Type, x.Required)).ToList(),
Placeholders = BuildPlaceholders(),
};
public LoadedTemplate BuildLoaded()
@@ -106,6 +108,24 @@ public partial class DesignerViewModel : ObservableObject
public ITemplateDataProvider BuildDataProvider() => new DesignerDataProvider(Placeholders.ToDictionary(
x => x.Name.Trim(), x => x.ToValue(), StringComparer.Ordinal));
public DesignerPlaceholder AddPlaceholder()
{
var existing = Placeholders.Select(x => x.Name).ToHashSet(StringComparer.Ordinal);
var index = Placeholders.Count + 1;
while (existing.Contains($"Feld{index}")) index++;
var placeholder = new DesignerPlaceholder($"Feld{index}", PlaceholderType.Text, false, "Beispiel");
Placeholders.Add(placeholder); SelectedPlaceholder = placeholder; CanExport = false;
SetStatus($"Platzhalter „{placeholder.Name}“ angelegt. Details können jetzt bearbeitet werden.", false);
return placeholder;
}
public void RemoveSelectedPlaceholder()
{
if (SelectedPlaceholder is not { } selected) return;
Placeholders.Remove(selected); SelectedPlaceholder = null; CanExport = false;
SetStatus($"Platzhalter „{selected.Name}“ entfernt.", false);
}
public void Load(LoadedTemplate template, string layoutSource)
{
TemplateId = template.Manifest.Id; TemplateName = template.Manifest.Name; Description = template.Manifest.Description;
@@ -118,6 +138,7 @@ public partial class DesignerViewModel : ObservableObject
Placeholders.Clear();
foreach (var placeholder in template.Manifest.Placeholders)
Placeholders.Add(new(placeholder.Name, placeholder.Type, placeholder.Required, DesignerPlaceholder.SampleFor(placeholder.Type)));
SelectedPlaceholder = Placeholders.FirstOrDefault();
Assets.Clear(); AssetItems.Clear();
foreach (var asset in template.Assets) AddOrReplaceAsset(asset.Key, asset.Value, keepName: true);
RefreshAssetUsage();
@@ -163,6 +184,20 @@ public partial class DesignerViewModel : ObservableObject
return result;
}
private List<PlaceholderDefinition> BuildPlaceholders()
{
var names = new HashSet<string>(StringComparer.Ordinal);
var result = new List<PlaceholderDefinition>(Placeholders.Count);
foreach (var placeholder in Placeholders)
{
var name = placeholder.Name.Trim();
if (name.Length == 0) throw new InvalidDataException("Ein Platzhaltername darf nicht leer sein.");
if (!names.Add(name)) throw new InvalidDataException($"Platzhalter „{name}“ ist mehrfach definiert.");
result.Add(new(name, placeholder.Type, placeholder.Required));
}
return result;
}
private static ITemplateDataProvider BuildSampleDataProvider(TemplateManifest manifest) =>
new DesignerDataProvider(manifest.Placeholders.ToDictionary(x => x.Name,
x => new DesignerPlaceholder(x.Name, x.Type, x.Required, DesignerPlaceholder.SampleFor(x.Type)).ToValue(),
+20 -9
View File
@@ -92,23 +92,34 @@
</Grid>
<Grid ColumnDefinitions="*,Auto"><TextBlock Text="Platzhalter &amp; Beispieldaten" Classes="section"/>
<Button Grid.Column="1" Content="" Click="OnAddPlaceholder"/></Grid>
<Button Grid.Column="1" Content=" Platzhalter" Click="OnAddPlaceholder"/></Grid>
<DataGrid x:Name="PlaceholderGrid" ItemsSource="{Binding Placeholders}" SelectedItem="{Binding SelectedPlaceholder}"
AutoGenerateColumns="False" Height="210" CanUserResizeColumns="True">
AutoGenerateColumns="False" Height="180" CanUserResizeColumns="True" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="*"/>
<DataGridTextColumn Header="Typ" Binding="{Binding Type}" Width="105" IsReadOnly="True"/>
<DataGridTextColumn Header="Typ" Binding="{Binding Type}" Width="105"/>
<DataGridCheckBoxColumn Header="Pflicht" Binding="{Binding Required}" Width="58"/>
<DataGridTextColumn Header="Beispiel" Binding="{Binding Sample}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
<Grid ColumnDefinitions="Auto,10,*">
<Button Content="Markierten Platzhalter entfernen" Click="OnRemovePlaceholder"/>
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
<TextBlock Text="Typ:" VerticalAlignment="Center"/>
<ComboBox Width="130" ItemsSource="{Binding PlaceholderTypes}" SelectedItem="{Binding SelectedPlaceholder.Type}"/>
<Border Padding="10" BorderBrush="#CBD5E1" BorderThickness="1" CornerRadius="4">
<StackPanel Spacing="8">
<TextBlock Text="Ausgewählten Platzhalter bearbeiten" FontWeight="SemiBold"/>
<Grid ColumnDefinitions="*,10,*">
<StackPanel><TextBlock Text="Name" Classes="label"/>
<TextBox Text="{Binding SelectedPlaceholder.Name, Mode=TwoWay}" PlaceholderText="z. B. Empfaenger"/></StackPanel>
<StackPanel Grid.Column="2"><TextBlock Text="Datentyp" Classes="label"/>
<ComboBox ItemsSource="{Binding PlaceholderTypes}"
SelectedItem="{Binding SelectedPlaceholder.Type, Mode=TwoWay}"/></StackPanel>
</Grid>
<CheckBox Content="Pflichtwert" IsChecked="{Binding SelectedPlaceholder.Required, Mode=TwoWay}"/>
<StackPanel><TextBlock Text="Beispielwert für die Vorschau" Classes="label"/>
<TextBox Text="{Binding SelectedPlaceholder.Sample, Mode=TwoWay}" AcceptsReturn="True"
MinHeight="58" TextWrapping="Wrap" PlaceholderText="Beispieldaten eingeben"/></StackPanel>
<Button Content="Ausgewählten Platzhalter entfernen" HorizontalAlignment="Left"
Click="OnRemovePlaceholder"/>
</StackPanel>
</Grid>
</Border>
<Grid ColumnDefinitions="*,Auto"><TextBlock Text="Paket-Assets" Classes="section"/>
<Button Grid.Column="1" Content=" Bild importieren …" Click="OnImportAsset"/></Grid>
@@ -27,8 +27,7 @@ public partial class MainWindow : Window
_viewModel.Reset(); _currentPackagePath = null; UpdateDocumentTitle();
}
private void OnExit(object? sender, RoutedEventArgs e) => Close();
private void OnAddPlaceholder(object? sender, RoutedEventArgs e) =>
_viewModel.Placeholders.Add(new($"Feld{_viewModel.Placeholders.Count + 1}", PlaceholderType.Text, false, "Beispiel"));
private void OnAddPlaceholder(object? sender, RoutedEventArgs e) => _viewModel.AddPlaceholder();
private void OnAddMetadata(object? sender, RoutedEventArgs e)
{
var item = new DesignerMetadata($"custom-{_viewModel.MetadataItems.Count + 1}", "");
@@ -39,11 +38,7 @@ public partial class MainWindow : Window
if (_viewModel.SelectedMetadata is not { } selected) return;
_viewModel.MetadataItems.Remove(selected); _viewModel.SelectedMetadata = null; _viewModel.CanExport = false;
}
private void OnRemovePlaceholder(object? sender, RoutedEventArgs e)
{
if (this.FindControl<DataGrid>("PlaceholderGrid")?.SelectedItem is DesignerPlaceholder selected)
_viewModel.Placeholders.Remove(selected);
}
private void OnRemovePlaceholder(object? sender, RoutedEventArgs e) => _viewModel.RemoveSelectedPlaceholder();
private void OnAddElement(object? sender, RoutedEventArgs e)
{ try { _viewModel.AddElement(); } catch (Exception ex) { _viewModel.SetStatus(ex.Message, true); } }
private void OnMeasureOverlayMode(object? sender, RoutedEventArgs e)