#region Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;

#endregion

namespace RevitAddinWallMulti
{
    [Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Application app = uiapp.Application;
            Document doc = uidoc.Document;

            try
            {
                // 選択フィルターを設定
                WallSelectionFilter filter = new WallSelectionFilter(doc);

                // フィルター付きでユーザーに壁インスタンスを複数選択してもらう
                IList<Reference> refences = uidoc.Selection.PickObjects(ObjectType.Element, filter, "壁を複数選べます。キャンセルするにはESCを押します");

                //選ばれた要素を表示する
                foreach (Reference myRef in refences)
                {
                    // 選択された要素を取得
                    Element selectElement = doc.GetElement(myRef);

                    // ファミリ名、タイプ名、カテゴリを取得
                    Wall wall = selectElement as Wall;
                    string familyName = wall.WallType.FamilyName;
                    string typeName = wall.WallType.Name;
                    string categeryName = selectElement.Category.Name;

                    // 結果を表示
                    TaskDialog.Show("選択された要素",
                        $"要素カテゴリ: {categeryName}\n" +
                        $"ファミリ名: {familyName}\n" +
                        $"タイプ名: {typeName}");
                }
                return Result.Succeeded;
            }
            catch (Autodesk.Revit.Exceptions.OperationCanceledException)
            {
                // ユーザーがキャンセルした場合
                return Result.Cancelled;
            }
            catch (Exception ex)
            {
                // その他のエラーが発生した場合

                message = $"エラーが発生しました: {ex.Message}";
                return Result.Failed;
            }
        }
    }
    public class WallSelectionFilter : ISelectionFilter
    {
        private readonly Document doc;
        //コンストラクタ
        public WallSelectionFilter(Document doc)
        {
            this.doc = doc;
        }
        //要素の選択を許可するかどうかのメソッド
        public bool AllowElement(Element elem)
        {
            if (elem is Autodesk.Revit.DB.Wall)
            {
                return true;
            }

            return false;
        }
        //要素の面やエッジなどジオメトリへの参照を選択できるかどうかのメソッド
        public bool AllowReference(Reference reference, XYZ position)
        {
            return false;
        }
    }
}
