C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

3DPDFと、おまけ

以前、CATIAからフリーソフトで3DPDFを作成する手順を
"Unofficial CATIA User Forum"  に書いたので
再度覚書として記載するついでに、最近は新たな
ソフトが無いかな? と思い探してみました。

○Bentley View V8i (要登録)
個人的にはこれが安定しているかなぁ と感じました。
細かく書かれている方がいらっしゃるので、こちらをご覧になると
良いかと思います。
フリーのツールで3D PDFを作成する方法 – FM575

CATIAの場合、直接インポートが出来るフォーマットが無さそうな為、
CATIA(wrl) → MeshLab(obj) → Bentley View
で可能でした。面倒な上、色が抜けてしまいます。
(色については wrl でエクスポートした時点で、抜けてます)


○DesignSpark Mechanical (確か要登録)
出た当時試してみました。 ちょっと自由曲面の面が抜けたりしていた
印象がありますが、最近はどうでしょうか?
こちらに方法が記載されていました。
[DSM] 3DデザインをPDFでシェア!

CATIAの場合ですが、こちらにインポート可能なフォーマット記載されており
利用できるインポート/エクスポート形式は? – 各サービスのサポート
"STEP (読み取りのみ)" となっています。3DPDFでエクスポートを含め
"読み取りのみ"  なのでしょうかねぇ?(未テストです)

以前試したときは
CATIA(wrl) → MeshLab(obj) → DesignSpark Mechanical
で行いました。


Fusion360 プラグイン (要 AutodeskID)
こちらはトライアル版で、10回まで可能なようです。
3D PDF Exporter for Autodesk® Fusion 360™ - Trial | Fusion 360 | Autodesk App Store
以前試したときは、カラーについては未対応 となっていましたが、
バージョンUpしカラー対応したっぽく記載されていましたが、色抜けます…。
(未確認ですが、面の色ではなくマテリアルのテクスチャじゃないと駄目なのかも知れません)
デフォルトではトレランス甘く、トレランスhighでは処理が異常なほど遅いです。
CADデータから作成可能なのは魅力的なのですが。


○EnSuite-View (要 各種アカウント)
今回発見したのはこちら。
EnSuite-View - 3D Free CAD Viewer, Productivity Tools and export files to IGES/STEP/3DPDF
これ自体は登録の必要が無かったのですが、これらのどれかの
アカウントが必要です。
f:id:kandennti:20171117172643p:plain
こちら基本的にビュアーで、ライセンス無しでも主要CADのネイティブデータの閲覧が
可能なようです。
実際に3DPDFのエクスポートを試してみたものの、3回中3回ソフトが落ちる
と言う状況で、確認出来ていません。
メッセージからして5回までの制限のようで、これはフリーソフトと言うより
トライアル版のような気がするのですが…。


○Manufacturing Data Exchange Utility (有償)
おまけです。 こちらPowerMill導入時、一緒にインストールされる変換ソフトです。
こちらに記載した、"Delcam Exchange" のバージョンUp版です。
CATIA V5 FreeなViewer - C#ATIA
これが手に入ったので、今のところフリーソフトに頼らなくて済むようになりました。


3DPDFとは無関係なのですが、こちらも見つけたのでご紹介。

○Explore 3D (場合によっては 要登録)
Winエクスプローラのプレビュー画面に、CADファイルの情報を表示させると言う
ちょっと今までに見たことが無かったソフトです。
http://www.cadcam-e.com/Explore3D/
こちらも、ライセンス無しでも主要CADのネイティブデータ情報が見れます。
これ、CATIAライセンスのある方でも良いかも知れません。

AssemblyTreeが表示されるので、SubAssyを持ったデータの場合、
複数CATProductがあり、ネーミングルール等が無いと直ぐには一番Topの
ファイルがわかりません。 が、これの場合はクリックするだけで
探し出せるような気がしてます。
f:id:kandennti:20171117172656p:plain

又、CATDrawingの場合サムネイルが表示されます。
f:id:kandennti:20171117172705p:plain
雰囲気しか見れませんけど。
と、ここまでは登録不要です。

3DCADデータの場合、小さいですが3Dビュア-として利用出来るようです。
"3D" を押すと、アクセスコードの入力を催促されました。
"ブログの所で登録しろ" とメッセージが出るので、登録したのですが
1日以上経ってもお返事来ません・・・ので未確認です。



話を戻しますが、テストで作成した3DPDFファイルをこちらにUpしました。
GrabCAD - CAD library
・Bentley View V8i
Fusion360 プラグイン(トレランス LowとMid)
・Manufacturing Data Exchange Utility
Fusion360プラグインのトレランスhighは、データが大きすぎる為、止めました。

フリーソフトであれば、Bentley View V8i でしょうかねぇ。
(基本的にあまり必要じゃないのですが、営業さん向け用とかです)

AutodeskとDropbox

こんな記事見つけました。
DropboxがAutodeskを統合、大きな設計ファイルのコラボレーションがクラウドを意識せずにできる | TechCrunch Japan
AutoCadのデータだけのようですね。 うちには無いですし
受け取ることも無いです。

これは、Autodesk Forgeを利用しているのかな? "開発プラットフォーム" って
記載されているけど、未だに何なのか良くわからない Forge。

Dassaultは未だに、DraftSightと3DXML playerぐらいだし。
(3DXMLのフォーマットも公開していないと思う)
Autodeskえらいなぁ

背景色を変更・復元する

タイトルが異なりますが、こちらの続きです。
画面キャプチャをクリップボードに保存する - C#ATIA

単に背景色を切り替えるマクロです。
但し元の背景色に復元出来る様に、変更前の背景色RGBをパラメータに
保存しています。
(外部ファイルや何処かのプロパティに書き出すより、自然かと思います)

'vba sample_ChangeBackColor ver0.0.1 by Kantoku
'CATIAの背景色を変更・復元

Option Explicit

'背景色をバックアップするパラメータ名
Private Const BACKCOLOR_PRAM_NAME = "BackColorRGB"

'変更後背景色
Private Const BACKCOLOR = "255,255,255"

Sub CATMain()
    Dim Doc As Document
    Set Doc = CATIA.ActiveDocument
    
    Dim Msg As String
    
    Dim Prms As Parameters
    Set Prms = Get_Prms(Doc)
    If Prms Is Nothing Then
        Msg = "ProductかPartで使用してください"
        MsgBox Msg
        Exit Sub
    End If
    
    Msg = "背景色を変更しますか?" & vbNewLine & _
        "はい : 背景色を変更(RGB:" & BACKCOLOR & ")" & vbNewLine & _
        "いいえ : バックアップしている背景色に復元" & vbNewLine & _
        "キャンセル : 中止"
            
    Select Case MsgBox(Msg, vbYesNoCancel + vbQuestion)
        Case vbYes
            Call ChangeBackColor(Prms) '白に変更
        Case vbNo
            Call RestorationBackColor(Prms) '復元
        Case Else
            Exit Sub
    End Select
    
End Sub

'復元
Sub RestorationBackColor(ByVal Prms As Parameters)
    Dim Msg As String
    
    If Not Is_ExistsPrm(Prms, BACKCOLOR_PRAM_NAME) Then
        Msg = "バックアップしている背景色が有りませんでした"
        MsgBox Msg, vbOKOnly + vbExclamation
        Exit Sub
    End If
    
    Dim Prm As StrParam
    Set Prm = Prms.Item(BACKCOLOR_PRAM_NAME)
    
    If Not Is_RGB_Str(Prm.Value) Then
        Msg = "バックアップしている背景色パラメータが不正です"
        MsgBox Msg, vbOKOnly + vbExclamation
        Exit Sub
    End If
    
    Call Update_BackRGB(Prm.Value)
    
    Dim Sel As Selection
    Set Sel = CATIA.ActiveDocument.Selection
    With Sel
        .Clear
        .Add Prm
        .Delete
    End With
End Sub

'BACKCOLORに変更
Private Sub ChangeBackColor(ByVal Prms As Parameters)
    Dim Msg As String
    
    Dim Prm As StrParam
    If Is_ExistsPrm(Prms, BACKCOLOR_PRAM_NAME) Then
        Set Prm = Prms.Item(BACKCOLOR_PRAM_NAME)
        
        Msg = "既に背景色のバックアップがありますが、" & _
            "作業を続けますか?" & vbNewLine & _
            "はい : 新たにバックアップし、作業を進める" & vbNewLine & _
            "いいえ : バックアップは変更せず、作業を進める" & vbNewLine & _
            "キャンセル : 中止"
            
        Select Case MsgBox(Msg, vbYesNoCancel + vbQuestion)
            Case vbYes
                Prm.Value = Get_BackRGB_ToStr()
            Case vbNo
                '何もしない
            Case Else
                Exit Sub
        End Select
    Else
        Set Prm = Prms.CreateString(BACKCOLOR_PRAM_NAME, "")
        Prm.Value = Get_BackRGB_ToStr()
    End If
    
    Call Update_BackRGB(BACKCOLOR)
    'Prm.Hidden = True '非表示
End Sub


' --- サポート関数 ---
Private Function Is_RGB_Str(ByVal Str As String) As Boolean
    Is_RGB_Str = False
    
    Dim Ary As Variant
    Ary = Split(Str, ",")
    If Not UBound(Ary) = 2 Then Exit Function
    
    Dim i As Long
    For i = 0 To 2
        If Not IsNumeric(Ary(i)) Then Exit Function
        If Not Ary(i) = CLng(Ary(i)) Then Exit Function
    Next
    
    Is_RGB_Str = True
End Function

Private Sub Update_BackRGB(ByVal RGB_Str As String)
    Dim VisSetAtt As VisualizationSettingAtt
    Set VisSetAtt = CATIA.SettingControllers.Item( _
        "CATVizVisualizationSettingCtrl")
        
    Dim Rgb As Variant
    Rgb = Split(RGB_Str, ",")

    Call VisSetAtt.SetBackgroundRGB(Rgb(0), Rgb(1), Rgb(2))
    VisSetAtt.SaveRepository
End Sub

Private Function Get_BackRGB_ToStr() As String
    Dim VisSetAtt As VisualizationSettingAtt
    Set VisSetAtt = CATIA.SettingControllers.Item( _
        "CATVizVisualizationSettingCtrl")
    
    Dim ActColor(2) As Long
    Call VisSetAtt.GetBackgroundRGB( _
        ActColor(0), ActColor(1), ActColor(2))
    
    Get_BackRGB_ToStr = Join( _
        Array(ActColor(0), ActColor(1), ActColor(2)), ",")
End Function

Private Function Init_Prm(ByVal Prms As Parameters, _
                          ByVal Name As String) As Parameter
    Set Init_Prm = Prms.CreateString(BACKCOLOR_PRAM_NAME, "")
End Function

Private Function Is_ExistsPrm(ByVal Prms As Parameters, _
                              ByVal Name As String) As Boolean
    Dim Prm As Parameter
    
    On Error Resume Next
        Set Prm = Prms.Item(Name)
    On Error GoTo 0
    
    Is_ExistsPrm = Not (Prm Is Nothing)
    
    If Not TypeName(Prm) = "StrParam" Then
        Is_ExistsPrm = False
        '文字型タイプじゃない同一名のパラメータがある- 未対応
    End If
End Function

Private Function Get_Prms(ByVal Doc As Document) As Parameters
    Set Get_Prms = Nothing
    Select Case TypeName(Doc)
        Case "ProductDocument"
            Set Get_Prms = Doc.Product.Parameters
        Case "PartDocument"
            Set Get_Prms = Doc.Part.Parameters
    End Select
End Function

定数 "BACKCOLOR_PRAM_NAME" と同一名の文字型以外のパラメータが存在していると
上手く行かないです・・・。(対応策を深く考えませんでした)

又、KCLを利用しなかったのでDocumentのチェックがやや甘めです。

変更・復元を一つのマクロ(最初のMsgboxで切り替え)で行っている為、
使い勝手がイマイチなのですが、ブログでFormのコードをUp出来ないので
ご勘弁を。

正直な所、このようなマクロよりキャプチャをジャンジャン作るマクロの方が、
効率が良い気がするのですが・・・。

例えば、データをズーム・スピンさせながら、スペースキーを押すたびに
キャプチャファイルを作る とか、
スペースキーを押すたびにExcelにキャプチャを貼り付けるとか・・・。
(当方Excelが古いため試せませんが、ひょっとしたらCATIAから
Excel操作できるのかな?)

バインディングに苦しむ

昔、挑戦していた時もこれに悩まされてました。
XAMLデザイナでViewModelが存在しないと言われた場合のメモ - いろいろ備忘録日記

現象は同じだけど、プロジェクトはネットワークドライブじゃ無くCドライブ。
ひょっとしたらバインディングをコードビハインドすれば
解決するかも知れないけど、XAML側で行いたい。

全然進まない・・・。

画面キャプチャをクリップボードに保存する

「CATIAで背景色を白にした状態で、画面のキャプチャをクリップボードに取得したい」
と相談を頂きました。

クリップボードではなく、ファイルとしてであればこちらの方法がお手軽かと
思います。
背景の設定を維持しつつ背景を白でキャプチャを行う | PLM Tips Magazine

'vba sample_Capture2Clipboard ver0.0.1 by Kantoku
'CATIAのキャプチャをクリップボードに保存

'--- WinAPI ---
'capture - https://qiita.com/nezuq/items/95cad79d9a9dd920d30e
#If VBA7 And Win64 Then
    Private Declare PtrSafe Sub keybd_event Lib "user32" ( _
    ByVal bVk As Byte, _
    ByVal bScan As Byte, _
    ByVal dwFlags As Long, _
    ByVal dwExtraInfo As Long)
#Else
    Private Declare Sub keybd_event Lib "user32" ( _
    ByVal bVk As Byte, _
    ByVal bScan As Byte, _
    ByVal dwFlags As Long, _
    ByVal dwExtraInfo As Long)
#End If

Const VK_SNAPSHOT = &H2C             '[PrintScrn]キー

Const KEYEVENTF_EXTENDEDKEY = &H1    'キーを押す
Const KEYEVENTF_KEYUP = &H2          'キーを放す

'wait
#If VBA7 Then
    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
    Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If

'--- 設定 ---
'キャプチャ時の背景色 RGB
Private Const BACKCOLOR = "255,255,255"

'キャプチャ取得待ち時間 ここの時間は調整してください
Private Const WAITTIME = 200

Option Explicit

Sub CATMain()
    '現在の背景色
    Dim VisSetAtt As VisualizationSettingAtt
    Set VisSetAtt = CATIA.SettingControllers.Item("CATVizVisualizationSettingCtrl")

    Dim ActColor(2) As Long
    Call VisSetAtt.GetBackgroundRGB(ActColor(0), ActColor(1), ActColor(2))
    
    '背景色変更
    Dim rgb As Variant
    rgb = Split(BACKCOLOR, ",")

    Call VisSetAtt.SetBackgroundRGB(rgb(0), rgb(1), rgb(2))
    VisSetAtt.SaveRepository
    
    If MsgBox("キャプチャしますか?", vbYesNo + vbInformation) = vbYes Then
        Call Sleep(WAITTIME)
        Call Exec_Capture 'キャプチャ
    End If
    
    '背景色を戻す
    Call VisSetAtt.SetBackgroundRGB(ActColor(0), ActColor(1), ActColor(2))
    VisSetAtt.SaveRepository
End Sub

'キャプチャ
Private Sub Exec_Capture()
    AppActivate CATIA.Caption, True
    
    keybd_event &HA4, 0&, &H1, 0&
    keybd_event vbKeySnapshot, 0&, &H1, 0&
    keybd_event vbKeySnapshot, 0&, &H1 Or &H2, 0&
    keybd_event &HA4, 0&, &H1 Or &H2, 0&
End Sub

32bitでも対応できるようにしたつもりですが、試す環境が無い為
未テストです。

WinAPIでPrintScrnキーを押しているのですが、タイミングが難しく
確認用のダイアログを出したり、ウェイトしたりしてます。
環境によってはダイアログの残像が残ってしまう可能性があるため、

Private Const WAITTIME = 200

の数値を修正して頂く必要があるかもしれません。
f:id:kandennti:20171114155030p:plain

又、最初に紹介した方法では、アクティブなウィンドウをキャプチャしたファイルが出来上がるのに
対して、このマクロではCATIA全体のキャプチャになってしまう為、イマイチです。
(ウィンドウハンドルとか取得すれば何とかなるのかな?)

CATIAのマクロをDotNetで作る事をオススメしない理由

MVVMお勉強中ですが、イヤになってきたので久々にC#でCATIAの
マクロをちょっと作ろうかなぁ と思ったのですが、諦めました。

何時かは書こうかと思っていたので、折角の機会なので。

1.マクロの記録が取れない

結構重要です。 個人的には各コマンド類(~Factory.AddNew~メソッド類)
や検索キーワード(Selection.Search "~")等は、イチイチ覚えていません。
必要な時に記録を取って、必要な部分だけ(大半が2行)コピーし後は
捨てています。こちらのマクロを作ったのは、その為です。
GrabCAD - CAD library


2.参照設定がシンドイ

こちらでは参照設定の方法を記載しましたが
DotNetでCATIA V5のマクロを作成する際の準備 - C#ATIA

こちらのコメント部に、imihitoさんアドバイスを頂きました。
Excelフォームボタンからマクロの起動 (未確認) - C#ATIA

CATIAっぽい全てのものを設定する必要は無いのですが、
結果的に何の参照が不足しているのかわからず、VBエディターを
開き、オブジェクトブラウザで該当するファイルを調べまくっている
と言うのが本音です。

3.デバッグが辛い

IDEを利用する利用の1つが、デバッグの行いやすさじゃないかと
思います。(インテリセンスもあるかもしれませんが)
個人的にはローカルウィンドウが重要で、変数の中身の状態が確認出来る
だけではなく、プロパティ類の中身をさかのぼって確認出来る点は
非常にありがたく、未知のオブジェクトを調べる際はかなり重宝します。
ところが、C#(DotNet)ではダメなんです。

こちらはVBAで"形状セット1"を選択した状態です。
f:id:kandennti:20171103175501p:plain
スケッチやジオメトリ(点・線・面)等も確認可能ですし、Parentをさかのぼって
行けばPartやPartDocumentも取得可能です。
(Documentが取得できれば、大半 事が足ります)

一方、C#の場合はこちら。
f:id:kandennti:20171103175513p:plain
"形状セット1"の名前すら確認出来ない状態です。 種類の部分は
”MECMOD.HybridBod{System.__ComObject}”と表示されていますが
これは形状セットとわかっている為、キャストした状態だからです。
キャストしないとこんな感じです。
f:id:kandennti:20171103175523p:plain
"INFITF.CATBaseDispatch" じゃ何だかわからないです。

GetTypeメソッドを利用しても

{Name = "__ComObject" FullName = "System.__ComObject"}

と返って来るだけ。 COMオブジェクトだってことは、GetTypeする前から
知ってます・・・。

COM相互運用が原因だとはわかっているのですが、
「動くようにしましたよ」ってだけで同等ではないです。

4.CATSafeArrayVariantが機能していない(と思った)

今日わかったのがこれです。これが書きたかったんです。

"CATSafeArrayVariant" は、点の座標値等受け取る際のもので
Variant配列です。 単純に面を選択し重心を所得する
VBAのコードです。

'vba using-'KCL0.0.12'
Sub CATMain()
    If Not CanExecute("PartDocument") Then Exit Sub
    
    Dim msg$: msg = "面を選択"
    Dim elm As SelectedElement
    Set elm = KCL.SelectElement(meg, "Face")
    If elm Is Nothing Then Exit Sub
    
    Dim doc As PartDocument
    Set doc = elm.Document
    
    Dim ref As Reference
    Set ref = elm.Reference
    
    Dim spa_wb As Object
    Set spa_wb = doc.GetWorkbench("SPAWorkbench")
    
    Dim mes As Variant 'Measurable
    Set mes = spa_wb.GetMeasurable(ref)
    
    Dim cog(2) As Variant 'これが CATSafeArrayVariant
    Call mes.GetCOG(cog)
    
    Debug.Print "重心 : "; Join(cog, ",")
End Sub

最後の方の "cog(2)" が、"CATSafeArrayVariant"です。
取得する際のGetCOGメソッドは、Measurableオブジェクトですが、
正しく型指定するとエラーになります。
(この手の、処理結果を引数のVariant配列に返す、悪魔仕様の
 ものは大半が型指定するとエラーになります)

同様の処理をC#でさせます。
(コードが長くなりすぎる為、例外処理はほぼしてません)

//cs ↓これらの参照設定必要です
using System.Runtime.InteropServices;
using INFITF;
using MECMOD;
using SPATypeLib;

    class Program
    {
        static void Main()
        {
            //モロモロ
            var cat = (INFITF.Application)Marshal.GetActiveObject("CATIA.Application");
            var doc = cat.ActiveDocument as MECMOD.PartDocument;

            //選択
            var msg = "面を選択";
            var sel = doc.Selection;
            var cancel_code = new string[] { "Cancel", "Undo", "Redo" };
            var filter = new object[] { "Face" };

            sel.Clear();
            string res = sel.SelectElement2(filter, msg, false);
            if (cancel_code.Any(x => x.ToString() == res)) { return; }

            var face_ref = sel.Item2(1).Reference;

            //SPAWorkbench
            var SpaWB = doc.GetWorkbench("SPAWorkbench") as SPAWorkbench;
            if (SpaWB == null) { return; }

            //Measurable
            var mes = SpaWB.GetMeasurable(face_ref);

            //重心
            var cog = new object[3];
            mes.GetCOG(cog);

            Console.WriteLine(string.Format(
                "重心 : {0},{1},{2}", cog[0], cog[1], cog[2]));
            Console.ReadKey();
        }
    {

VBAのVariant配列は、C#の場合object配列です。 これ

            mes.GetCOG(cog);

ここでエラーになる予定だったのですが、正しく処理してます・・・。
不安定ですね・・・。本当は

            var mes_oj = mes as object;
            mes_oj.GetCenter(cog);

だと、型付けが邪魔で出来ないから

            dynamic mes_oj = mes as object;
            mes_oj.GetCenter(cog);

にしたけど、やっぱりエラーになるよ って書きたかったのですけどね。

こちらでも機能してないって書いてあるんですけど。
http://www.coe.org/p/fo/st/per=10&sort=0&thread=24278&p=1




他にも 
C#だと "遅い" → どうでも良いです。
DLL化すれば同レベルで処理します。(要レジストリに登録ですが)

C#だと配布しやすい → catvbsやvbsでも同様です。

・catvbsやvbsだとソースコード見られちゃう
  → CATVBAでパスワード付けるか。
 vbsを暗号化
VBScriptの暗号化 | VBScript さんま屋


・他言語熟知者にとってのVBAの学習コスト 
  →VBA異質だから、結構納得。

検索すると結構 "PythonでCATIAのマクロ" がHitするのですが、
動的型付け言語の方がC#より向いている気がします。

現状、DotNetで作る価値が見つかりませんね。

※追記です
GetCOGのパラメータです。
f:id:kandennti:20171106092508p:plain
配列としか出ていませんでした。

「簡単」すら難しい

過去に社内で使うものはWPFを素のままで作成しましたが、しんどいので
Prismを利用する事にしました。
基本的なサンプルから練習しようとこちらのサイトを参考にさせてもらいました。

簡単MVVM入門 with Prism - Qiita

個人的には、「簡単」すら難しかったです・・・。


VS2017 Community で行っていますが、NuGetパッケージマネージャーは改めて
インストールする必要は無かったです。

「Prism Template Pack」ではなく、NuGetの方の「Prism v5.0.0」です。 
僕が行った際、ターゲットフレームワークは 「.NET Framework 4.0」では、
「Prism.Composition」だけが、インストール出来ませんでした。(悩みました)
最低でも 4.5 は必要なのではないか? と思われます。


まず新規に作成する際、Prismのテンプレートではないです。(ここでも悩みました)
素の「WPFアプリ」から作成し、名前空間の記載から恐らくソリューションの状態は
各フォルダ毎に分けているっぽいので、こんな感じです。
f:id:kandennti:20171102143930p:plain

最後の部分ではViewについてはサラッとしか記載されていないのですが、
こんな感じで動きました。(恐らくPrismには無関係だからでしょう)

xaml

<!-- xaml View/View.xaml -->
<Window x:Class="Calclator.View.View"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Calclator.View"
        mc:Ignorable="d"
        Title="View" Height="140" Width="240">
    
    <Grid>
        <TextBox 
            x:Name="textBox" HorizontalAlignment="Left" Height="25" 
            Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding Path=X}" 
            VerticalAlignment="Top" Width="120"/>
        
        <TextBox 
            x:Name="textBox_Copy" HorizontalAlignment="Left" Height="25" 
            Margin="10,40,0,0" TextWrapping="Wrap" Text="{Binding Path=Y}" 
            VerticalAlignment="Top" Width="120"/>
        
        <TextBox 
            x:Name="textBox_Copy1" HorizontalAlignment="Left" Height="25" 
            Margin="10,70,0,0" TextWrapping="Wrap" Text="{Binding Path=Ans}" 
            VerticalAlignment="Top" Width="120"/>
        
        <Button 
            x:Name="button" Content="Button" HorizontalAlignment="Left" 
            Margin="140,10,0,0" VerticalAlignment="Top" Width="75" 
            Command="{Binding calcCommand}"/>
    </Grid>
</Window>

答えがTextBoxで良いのかな? とか有りますが、元の記載に合わせました。

コードビハインド側

//cs View.xaml.cs
using System.Windows;
using Calclator.ViewModel;

namespace Calclator.View
{
    /// <summary>
    /// View.xaml の相互作用ロジック
    /// </summary>
    public partial class View : Window
    {
        public View()
        {
            InitializeComponent();
            this.DataContext = new ViewModels();
        }
    }
}

テンプレートで出来あがるXAMLは削除した為、起動時にView.xamlが表示されるように
App.xaml(エントリーポイント?)も修正。

<!-- xaml App.xaml -->
<Application x:Class="Calclator.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Calclator"
             StartupUri="View/View.xaml">
    
    <Application.Resources>
         
    </Application.Resources>
</Application>

何で、C#はこんなにコード書かなきゃいけないんだろう?