File Layout -> group by Implements Interface creates an region for an interface without name

I've created a slightly complex File layout pattern. It handles Classes and has a Region that is grouped by implemnts interface. It looks like the pattern treats public members (methods, propertiers, …) as members of an “virtual" interface with the name “” (string.Empty) and creates a region with no name. It should create an own region for properies an indexers and an otherone for methods below the interface implementations region. 

Here ist the XAML: the relevant TypePattern-Fragment only

  <TypePattern DisplayName="Default Pattern" RemoveRegions="AllExceptGenerated">
   <Region Name=" Enums">
     <Entry DisplayName="Public Enums">
       <Entry.Match>
         <And>
           <Access Is="Public" />
           <Kind Is="Enum" />
         </And>
       </Entry.Match>
       <Entry.SortBy>
         <Name />
       </Entry.SortBy>
     </Entry>
   </Region>
   <Region Name=" Fields">
     <Entry DisplayName="Static Fields and Constants">
       <Entry.Match>
         <Or>
           <Kind Is="Constant" />
           <And>
             <Kind Is="Field" />
             <Static />
           </And>
         </Or>
       </Entry.Match>
       <Entry.SortBy>
         <Kind Is="0" Order="Constant Field" />
       </Entry.SortBy>
     </Entry>
     <Entry DisplayName="Fields">
       <Entry.Match>
         <And>
           <Kind Is="Field" />
           <Not>
             <Static />
           </Not>
         </And>
       </Entry.Match>
       <Entry.SortBy>
         <Readonly />
         <Name />
       </Entry.SortBy>
     </Entry>
   </Region>
   <Region Name=" Events and delegates">
     <Entry DisplayName="Entry">
       <Entry.Match>
         <Or>
           <Kind Is="Event" />
           <Kind Is="Delegate" />
         </Or>
       </Entry.Match>
       <Entry.SortBy>
         <Kind Is="Member" />
         <Access Is="0" />
         <Name />
       </Entry.SortBy>
     </Entry>
   </Region>
   <Region Name=" ctors">
     <Entry DisplayName="Constructors">
       <Entry.Match>
         <Or>
           <Kind Is="Constructor" />
           <Kind Is="Destructor" />
         </Or>
       </Entry.Match>
       <Entry.SortBy>
         <Static />
         <Access Is="0" />
       </Entry.SortBy>
     </Entry>
   </Region>
   <Region Name=" ${ImplementsInterface}">
     <Region.GroupBy>
       <ImplementsInterface />
     </Region.GroupBy>
     <Entry DisplayName="Events and Delegates">
       <Entry.Match>
         <And>
           <Or>
             <Kind Is="Event" />
             <Kind Is="Delegate" />
           </Or>
         </And>
       </Entry.Match>
       <Entry.SortBy>
         <Name />
       </Entry.SortBy>
     </Entry>
     <Region Name=" Commands">
       <Entry DisplayName="Interface Implementations Commands" Priority="100">
         <Entry.Match>
           <And>
             <Kind Is="Property" />
             <Type Is="System.Windows.Input.ICommand" />
           </And>
         </Entry.Match>
         <Entry.SortBy>
           <ImplementsInterface />
           <Kind Is="Member" />
           <Name />
         </Entry.SortBy>
       </Entry>
     </Region>
     <Entry DisplayName="Interface Properties">
       <Entry.Match>
         <Or>
           <Kind Is="Property" />
           <Kind Is="Indexer" />
         </Or>
       </Entry.Match>
       <Entry.SortBy>
         <ImplementsInterface />
         <Name />
       </Entry.SortBy>
     </Entry>
     <Entry DisplayName="Interface Methods">
       <Entry.Match>
         <Kind Is="Method" />
       </Entry.Match>
       <Entry.SortBy>
         <Name />
       </Entry.SortBy>
     </Entry>
   </Region>
   <Region Name=" ${Access} Properties and Indexers">
     <Region.GroupBy>
       <Access Is="0" />
     </Region.GroupBy>
     <Entry DisplayName="Properties, Indexers">
       <Entry.Match>
         <Or>
           <Kind Is="Property" />
           <Kind Is="Indexer" />
         </Or>
       </Entry.Match>
       <Entry.SortBy>
         <Name />
       </Entry.SortBy>
     </Entry>
   </Region>
   <Region Name=" ${Access} Methods">
     <Region.GroupBy>
       <Access Is="0" />
     </Region.GroupBy>
     <Region Name=" command actions" Priority="100">
       <Entry DisplayName="command actions" Priority="100">
         <Entry.Match>
           <And>
             <Kind Is="Method" />
             <Name Is="*CommandAction" />
           </And>
         </Entry.Match>
         <Entry.SortBy>
           <Name />
         </Entry.SortBy>
       </Entry>
     </Region>
     <Region Name=" event handler">
       <Entry DisplayName="Entry" Priority="100">
         <Entry.Match>
           <And>
             <Kind Is="Method" />
             <Name Is="\w+_\w+" />
           </And>
         </Entry.Match>
         <Entry.SortBy>
           <Name />
         </Entry.SortBy>
       </Entry>
     </Region>
     <Entry DisplayName="Entry">
       <Entry.Match>
         <Kind Is="Method" />
       </Entry.Match>
       <Entry.SortBy>
         <Access Is="0" />
         <Name />
       </Entry.SortBy>
     </Entry>
   </Region>
   <Region Name=" Other Members" Priority="25">
     <Entry DisplayName="All other members" Priority="25">
       <Entry.SortBy>
         <Kind Is="Member" />
         <Access Is="0" />
         <Name />
       </Entry.SortBy>
     </Entry>
   </Region>
   <Region Name=" Nested Types">
     <Entry DisplayName="Nested Types">
       <Entry.Match>
         <Kind Is="Type" />
       </Entry.Match>
     </Entry>
   </Region>
 </TypePattern>

The result looks like this:

using System;
using System.Threading.Tasks;

namespace Test;

public class TestClassA : TestClassBase, ITestA
{
    #region

    public string NickName { get; set; }

    public void DoSomeThing()
    {
    }

    private void DoSomeThingElse()
    {
    }

    #endregion

    #region ITest

    public override Task Initialize(int id)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region ITestA

    public string Description { get; set; }

    public string Name { get; set; }

    #endregion
}

public interface ITest
{
    #region Properties and Indexers

    int Id { get; set; }

    #endregion

    #region Methods

    Task Initialize();
    Task Initialize(int id);

    #endregion
}

public interface ITestA : ITest
{
    #region Properties and Indexers

    string Description { get; set; }
    string Name { get; set; }

    #endregion
}

public abstract class TestClassBase : ITest
{
    #region ITest

    public int Id { get; set; }

    public Task Initialize()
    {
        throw new NotImplementedException();
    }

    public abstract Task Initialize(int id);

    #endregion
}

I've played a little with the priorities. When I set the priority of the region for properties and for methods to High, the previos region for interface implementations stopps working.

The desired result looks like this:

public class TestClassA : TestClassBase, ITestA
{
    #region ITest

    public override Task Initialize(int id)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region ITestA

    public string Description { get; set; }

    public string Name { get; set; }

    #endregion


    #region  public Properties and Indexers
    public string NickName { get; set; }

    #endregion

    #region  public Methods
    public void DoSomeThing()
    {
    }

    #endregion

    #region  private Methods
    public void DoSomeThingElse()
    {
    }

    #endregion
}

 

My idea is to exclude the “virtual” interface with the empty name from the mplements interface region. But I could not figure out how to realize this.

Best regards 

Rene NIediek

0
3 comments

Hello Rene Niediek, thank you for your question. I was able to achieve the desired behavior. To do this, please add a logical container “AND” and a constraint “Implements Interface” to each item inside the #region  ${ImplementsInterface}. Below is an illustration and the contents of the XAML. Does it help?

<TypePattern DisplayName="Default Pattern" RemoveRegions="AllExceptGenerated">
    <Region Name=" Enums">
      <Entry DisplayName="Public Enums">
        <Entry.Match>
          <And>
            <Access Is="Public" />
            <Kind Is="Enum" />
          </And>
        </Entry.Match>
        <Entry.SortBy>
          <Name />
        </Entry.SortBy>
      </Entry>
    </Region>
    <Region Name=" Fields">
      <Entry DisplayName="Static Fields and Constants">
        <Entry.Match>
          <Or>
            <Kind Is="Constant" />
            <And>
              <Kind Is="Field" />
              <Static />
            </And>
          </Or>
        </Entry.Match>
        <Entry.SortBy>
          <Kind Is="0" Order="Constant Field" />
        </Entry.SortBy>
      </Entry>
      <Entry DisplayName="Fields">
        <Entry.Match>
          <And>
            <Kind Is="Field" />
            <Not>
              <Static />
            </Not>
          </And>
        </Entry.Match>
        <Entry.SortBy>
          <Readonly />
          <Name />
        </Entry.SortBy>
      </Entry>
    </Region>
    <Region Name=" Events and delegates">
      <Entry DisplayName="Entry">
        <Entry.Match>
          <Or>
            <Kind Is="Event" />
            <Kind Is="Delegate" />
          </Or>
        </Entry.Match>
        <Entry.SortBy>
          <Kind Is="Member" />
          <Access Is="0" />
          <Name />
        </Entry.SortBy>
      </Entry>
    </Region>
    <Region Name=" ctors">
      <Entry DisplayName="Constructors">
        <Entry.Match>
          <Or>
            <Kind Is="Constructor" />
            <Kind Is="Destructor" />
          </Or>
        </Entry.Match>
        <Entry.SortBy>
          <Static />
          <Access Is="0" />
        </Entry.SortBy>
      </Entry>
    </Region>
    <Region Name=" ${ImplementsInterface}">
      <Region.GroupBy>
        <ImplementsInterface />
      </Region.GroupBy>
      <Entry DisplayName="Events and Delegates">
        <Entry.Match>
          <And>
            <Or>
              <Kind Is="Event" />
              <Kind Is="Delegate" />
            </Or>
            <ImplementsInterface />
          </And>
        </Entry.Match>
        <Entry.SortBy>
          <Name />
        </Entry.SortBy>
      </Entry>
      <Region Name=" Commands">
        <Entry DisplayName="Interface Implementations Commands" Priority="100">
          <Entry.Match>
            <And>
              <Kind Is="Property" />
              <Type Is="System.Windows.Input.ICommand" />
              <ImplementsInterface />
            </And>
          </Entry.Match>
          <Entry.SortBy>
            <ImplementsInterface />
            <Kind Is="Member" />
            <Name />
          </Entry.SortBy>
        </Entry>
      </Region>
      <Entry DisplayName="Interface Properties">
        <Entry.Match>
          <Or>
            <And>
              <Kind Is="Property" />
              <ImplementsInterface />
            </And>
            <And>
              <Kind Is="Indexer" />
              <ImplementsInterface />
            </And>
          </Or>
        </Entry.Match>
        <Entry.SortBy>
          <ImplementsInterface />
          <Name />
        </Entry.SortBy>
      </Entry>
      <Entry DisplayName="Interface Methods">
        <Entry.Match>
          <And>
            <Kind Is="Method" />
            <ImplementsInterface />
          </And>
        </Entry.Match>
        <Entry.SortBy>
          <Name />
        </Entry.SortBy>
      </Entry>
    </Region>
    <Region Name=" ${Access} Properties and Indexers">
      <Region.GroupBy>
        <Access Is="0" />
      </Region.GroupBy>
      <Entry DisplayName="Properties, Indexers">
        <Entry.Match>
          <Or>
            <Kind Is="Property" />
            <Kind Is="Indexer" />
          </Or>
        </Entry.Match>
        <Entry.SortBy>
          <Name />
        </Entry.SortBy>
      </Entry>
    </Region>
    <Region Name=" ${Access} Methods">
      <Region.GroupBy>
        <Access Is="0" />
      </Region.GroupBy>
      <Region Name=" command actions" Priority="100">
        <Entry DisplayName="command actions" Priority="100">
          <Entry.Match>
            <And>
              <Kind Is="Method" />
              <Name Is="*CommandAction" />
            </And>
          </Entry.Match>
          <Entry.SortBy>
            <Name />
          </Entry.SortBy>
        </Entry>
      </Region>
      <Region Name=" event handler">
        <Entry DisplayName="Entry" Priority="100">
          <Entry.Match>
            <And>
              <Kind Is="Method" />
              <Name Is="\w+_\w+" />
            </And>
          </Entry.Match>
          <Entry.SortBy>
            <Name />
          </Entry.SortBy>
        </Entry>
      </Region>
      <Entry DisplayName="Entry">
        <Entry.Match>
          <Kind Is="Method" />
        </Entry.Match>
        <Entry.SortBy>
          <Access Is="0" />
          <Name />
        </Entry.SortBy>
      </Entry>
    </Region>
    <Region Name=" Other Members" Priority="25">
      <Entry DisplayName="All other members" Priority="25">
        <Entry.SortBy>
          <Kind Is="Member" />
          <Access Is="0" />
          <Name />
        </Entry.SortBy>
      </Entry>
    </Region>
    <Region Name=" Nested Types">
      <Entry DisplayName="Nested Types">
        <Entry.Match>
          <Kind Is="Type" />
        </Entry.Match>
      </Entry>
    </Region>
  </TypePattern>
1

Hello Maria,

thank you for providing a propper solution so fast. It seams to work as desiered.

If I unterstand that right, the conditions are not inherited to the child elements. In fact I was aware of this fact somehow deep in my brain. But …

thanks again

René

0

Hello Rene, it's great to hear that it helped! I'm not sure I understood the phrase “the conditions are not inherited to the child elements”. In fact, I don't see where the condition about implementing the interface could come from to the child elements. If you meant inheriting from the region name, then no, it is not inherited from the name. But maybe I'm missing something... Please correct me if I'm wrong.

0

Please sign in to leave a comment.