Q:

Find Out If Dynamic Placeholder Has Renderings

Is there a way to find out if a dynamic placeholder has renderings in it? I'm currently using Fortis Collection's implementation of dynamic placeholders which was included in the project through nuget. I've only done this with normal placeholders and it involved using the placeholder's name similar to this: https://stackoverflow.com/a/24362438/2597149. This won't work since I don't know the exact string of the placeholder to use.

A:

Updated
OK - so this is a lot more complex than I thought it might be. Basically, because of the way that Sitecore handles renderings and placeholders, there is no way of getting all the placeholder keys for a page. You can only list placeholder keys where rendering has been added to it.
Finding Rendering inside Dynamic Placeholders
You can easily find renderings that have been added to a dynamic placeholder, without knowing the full key name including the Guid:
Sitecore.Context.Page.Renderings
    .Where(r => r.Placeholder.StartsWith("PromoItems_", StringComparison.OrdinalIgnoreCase))

This code will get you the renderings that have been added to any of the PromoItems dynamic placeholders. This works because the dynamic placeholder code uses this format ({placeholderKey}_{renderingId}), to create the full dynamic placeholder key.
Getting a PlaceholderKey that has not been used
To get hold of a placeholder key that has not had any components added to it, you have to grab it when the page is being composed. When you add @Html.Sitecore().DynamicPlaceholder(), once it has worked out the key - it still just runs through the mvc.renderPlaceholder pipeline. In this pipeline, it calls a GetRenderings method that... wait for it... gets all the renderings for that placeholder key:
protected virtual IEnumerable<Rendering> GetRenderings(string placeholderName, RenderPlaceholderArgs args)
{
    string placeholderPath = PlaceholderContext.Current.ValueOrDefault(context => context.PlaceholderPath).OrEmpty();
    Guid deviceId = this.GetPageDeviceId(args);
    return args.PageContext.PageDefinition.Renderings.Where<Rendering>(r =>
    {
        if (!(r.DeviceId == deviceId))
            return false;
        if (!r.Placeholder.EqualsText(placeholderName))
            return r.Placeholder.EqualsText(placeholderPath);
        return true;
    });
}

Depending on what you wanted to do with that empty placeholder, you could override the PerformRendering processor and check if a rendering had components or not.
Here is an example that stores a list of keys in Sitecore.Context.Items, which you could then use somewhere else in the code:
public class PerformRendering: Sitecore.Mvc.Pipelines.Response.RenderPlaceholder.PerformRendering
{
    protected override void Render(string placeholderName, TextWriter writer, RenderPlaceholderArgs args)
    {
        var renderingsForPlaceholder = this.GetRenderings(placeholderName, args).ToList();
        if (!renderingsForPlaceholder.Any())
        {
            // Do something here? Maybe store it in Sitecore.Context.Items to be used later?
            var unusedPlaceholders = Sitecore.Context.Items["unusedPlaceholderKeys"] as List<string> ?? new List<string>();
            unusedPlaceholders.Add(placeholderName);
            Sitecore.Context.Items["unusedPlaceholderKeys"] = unusedPlaceholders;
        }

        foreach (Rendering rendering in renderingsForPlaceholder)
        {
            if (rendering != null)
            {
                using (this.CreateCyclePreventer(placeholderName, rendering))
                    this.ProcessRenderRendering(rendering, writer);
            }
        }
    }
}

Hopefully, that helps solve your problem!

