Improvements
This commit is contained in:
Родитель
ac29ed4794
Коммит
97e4572c39
|
@ -0,0 +1,61 @@
|
|||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using QuestPDF.Examples.Engine;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace QuestPDF.Examples
|
||||
{
|
||||
internal class MyComponent : IComponent
|
||||
{
|
||||
public ISlot Header { get; set; }
|
||||
public ISlot<string> Content { get; set; }
|
||||
|
||||
public void Compose(IContainer container)
|
||||
{
|
||||
container
|
||||
.Column(column =>
|
||||
{
|
||||
column.Item().Slot(Header);
|
||||
|
||||
foreach (var i in Enumerable.Range(1, 10))
|
||||
column.Item().Slot(Content, i.ToString());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class ComponentExamples
|
||||
{
|
||||
[Test]
|
||||
public void ComplexLayout()
|
||||
{
|
||||
RenderingTest
|
||||
.Create()
|
||||
.PageSize(PageSizes.A4)
|
||||
.ProducePdf()
|
||||
.ShowResults()
|
||||
.Render(content =>
|
||||
{
|
||||
content
|
||||
.Padding(10)
|
||||
.Border(1)
|
||||
.BorderColor(Colors.Grey.Medium)
|
||||
.Component<MyComponent>(component =>
|
||||
{
|
||||
component
|
||||
.Slot(x => x.Header)
|
||||
.Text("This is my text");
|
||||
|
||||
component.Slot(x => x.Content, (input, container) =>
|
||||
{
|
||||
container
|
||||
.Background(Placeholders.BackgroundColor())
|
||||
.Padding(5)
|
||||
.Text(input);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +1,53 @@
|
|||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using QuestPDF.Drawing.Exceptions;
|
||||
using QuestPDF.Elements;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace QuestPDF.Fluent
|
||||
{
|
||||
class ComponentDescriptor<T> where T : IComponent
|
||||
internal class ComponentDescriptor<TComponent> where TComponent : IComponent
|
||||
{
|
||||
public T Component { get; }
|
||||
public TComponent Component { get; }
|
||||
|
||||
public ComponentDescriptor(T component)
|
||||
public ComponentDescriptor(TComponent component)
|
||||
{
|
||||
Component = component;
|
||||
}
|
||||
|
||||
public IContainer Slot(Expression<Func<T, ISlot>> selector)
|
||||
public IContainer Slot(Expression<Func<TComponent, ISlot>> selector)
|
||||
{
|
||||
try
|
||||
AssureThatTheSlotIsNotConfiguredYet(selector);
|
||||
|
||||
var slot = new Slot();
|
||||
Component.SetPropertyValue(selector, slot);
|
||||
return slot;
|
||||
}
|
||||
|
||||
public void Slot<TArgument>(Expression<Func<TComponent, ISlot<TArgument>>> selector, Action<TArgument, IContainer> handler)
|
||||
{
|
||||
AssureThatTheSlotIsNotConfiguredYet(selector);
|
||||
|
||||
var slot = new Slot<TArgument>
|
||||
{
|
||||
var existingValue = Component.GetPropertyValue(selector);
|
||||
GetContent = argument =>
|
||||
{
|
||||
var container = new Container();
|
||||
handler(argument, container);
|
||||
return container;
|
||||
}
|
||||
};
|
||||
|
||||
Component.SetPropertyValue(selector, slot);
|
||||
}
|
||||
|
||||
if (existingValue != null)
|
||||
throw new DocumentComposeException($"The slot {selector.GetPropertyName()} of the component {(typeof(T).Name)} was already used.");
|
||||
private void AssureThatTheSlotIsNotConfiguredYet<TSlot>(Expression<Func<TComponent, TSlot>> selector) where TSlot : class
|
||||
{
|
||||
var existingValue = Component.GetPropertyValue(selector);
|
||||
|
||||
var slot = new Slot();
|
||||
Component.SetPropertyValue(selector, slot);
|
||||
return slot;
|
||||
}
|
||||
catch (DocumentComposeException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new DocumentComposeException("Every slot in a component should be a public property with getter and setter.");
|
||||
}
|
||||
if (existingValue != null)
|
||||
throw new DocumentComposeException($"The slot {selector.GetPropertyName()} of the component {(typeof(TComponent).Name)} was already used.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +63,7 @@ namespace QuestPDF.Fluent
|
|||
element.Component(new T(), null);
|
||||
}
|
||||
|
||||
static void Component<T>(this IContainer element, T component, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent
|
||||
internal static void Component<T>(this IContainer element, T component, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent
|
||||
{
|
||||
var descriptor = new ComponentDescriptor<T>(component);
|
||||
handler?.Invoke(descriptor);
|
||||
|
@ -62,15 +74,21 @@ namespace QuestPDF.Fluent
|
|||
component.Compose(element.Container());
|
||||
}
|
||||
|
||||
static void Component<T>(this IContainer element, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent, new()
|
||||
internal static void Component<T>(this IContainer element, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent, new()
|
||||
{
|
||||
element.Component(new T(), handler);
|
||||
}
|
||||
|
||||
static void Slot(this IContainer element, ISlot slot)
|
||||
internal static void Slot(this IContainer element, ISlot slot)
|
||||
{
|
||||
var child = (slot as Slot)?.Child;
|
||||
element.Element(child);
|
||||
}
|
||||
|
||||
internal static void Slot<TArgument>(this IContainer element, ISlot<TArgument> slot, TArgument argument)
|
||||
{
|
||||
var child = (slot as Slot<TArgument>)?.GetContent(argument) ?? Empty.Instance;
|
||||
element.Element(child);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using QuestPDF.Elements;
|
||||
|
||||
namespace QuestPDF.Infrastructure
|
||||
|
@ -11,7 +12,17 @@ namespace QuestPDF.Infrastructure
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface ISlot<T>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class Slot<T> : ISlot<T>
|
||||
{
|
||||
public Func<T, IElement> GetContent { get; set; }
|
||||
}
|
||||
|
||||
public interface IComponent
|
||||
{
|
||||
void Compose(IContainer container);
|
||||
|
|
Загрузка…
Ссылка в новой задаче