in source/dotnet/Library/AdaptiveCards.Rendering.Wpf/AdaptiveRenderContext.cs [264:350]
public FrameworkElement Render(AdaptiveTypedElement element)
{
FrameworkElement frameworkElementOut = null;
var oldAncestorHasFallback = AncestorHasFallback;
var elementHasFallback = element != null && element.Fallback != null && (element.Fallback.Type != AdaptiveFallbackElement.AdaptiveFallbackType.None);
AncestorHasFallback = AncestorHasFallback || elementHasFallback;
try
{
if (AncestorHasFallback && !element.MeetsRequirements(FeatureRegistration))
{
throw new AdaptiveFallbackException("Element requirements aren't met");
}
// Inputs should render read-only if interactivity is false
if (!Config.SupportsInteractivity && element is AdaptiveInput input)
{
var tb = AdaptiveTypedElementConverter.CreateElement<AdaptiveTextBlock>();
tb.Text = input.GetNonInteractiveValue() ?? "*[Input]*";
tb.Color = AdaptiveTextColor.Accent;
tb.Wrap = true;
InputValues.Add(input.Id, null);
Warnings.Add(new AdaptiveWarning(-1, $"Rendering non-interactive input element '{element.Type}'"));
frameworkElementOut = Render(tb);
}
if (frameworkElementOut == null)
{
var renderer = ElementRenderers.Get(element.GetType());
if (renderer != null)
{
var rendered = renderer.Invoke(element, this);
if (!String.IsNullOrEmpty(element.Id))
{
// The element is added to the dictionary if it's an action or if it's a card element and the height is auto
// as stretch items are enclosed in a panel that is added in AdaptiveContainerRenderer.AddContainerElements
if (!(element is AdaptiveElement) ||
(element is AdaptiveElement adaptiveElement && adaptiveElement.Height == AdaptiveHeight.Auto))
{
RenderedElementsWithId.Add(element.Id, rendered);
}
}
frameworkElementOut = rendered;
}
}
}
catch (AdaptiveFallbackException)
{
if (!elementHasFallback)
{
throw;
}
}
// If a container failed to render any of the children elements perform fallback
if (frameworkElementOut == null && (element is AdaptiveCollectionElement))
{
if (element.Fallback != null && element.Fallback.Type != AdaptiveFallbackElement.AdaptiveFallbackType.None)
{
if (element.Fallback.Type == AdaptiveFallbackElement.AdaptiveFallbackType.Drop)
{
Warnings.Add(new AdaptiveWarning(-1, $"Dropping element '{element.Type}' for fallback"));
}
else if (element.Fallback.Type == AdaptiveFallbackElement.AdaptiveFallbackType.Content && element.Fallback.Content != null)
{
// Render fallback content
Warnings.Add(new AdaptiveWarning(-1, $"Performing fallback for '{element.Type}' (fallback element type '{element.Fallback.Content.Type}')"));
RenderingFallback = true;
frameworkElementOut = Render(element.Fallback.Content);
RenderingFallback = false;
}
}
else if (AncestorHasFallback && !RenderingFallback)
{
throw new AdaptiveFallbackException();
}
else
{
Warnings.Add(new AdaptiveWarning(-1, $"No renderer for element '{element.Type}'"));
}
}
AncestorHasFallback = oldAncestorHasFallback;
return frameworkElementOut;
}