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

#endregion

namespace RevitAddinWallHeight
{
    [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);

                // フィルター付きでユーザーに壁インスタンスを選択してもらう
                Reference myRef = uidoc.Selection.PickObject(ObjectType.Element, filter, "壁を選択してください。キャンセルするにはESCを押します");

                // 選択された要素を取得
                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;

                //壁の高さを取得
                double height = wall.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).AsDouble();

                //内部単位をミリメートルに変換
                double heightInMM = (int)Math.Round(UnitUtils.ConvertFromInternalUnits(height, UnitTypeId.Millimeters), 0);

                // 結果を表示
                TaskDialog.Show("壁の情報",
                    $"壁の高さ: {heightInMM}\n" +
                    $"ファミリ名: {familyName} / " +
                    $"タイプ名: {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;
        }
    }
}