Windows Presentation Foundation (WPF)のGUIをMAXScriptで使ってみよう企画?です。

ライブラリ(DLL)にしてMAXScriptでアクセスするという感じ

Visual Studioで普通にWPFアプリケーションを作成すると普通に.exeになってしまうので、ちょっと回り道をします。

「WPF ユーザーコントロール ライブラリ」として作成し
ウインドウを追加

あとはゴリゴリ書きたいことを書くだけ

今回はこんな感じ

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace WpfControlLibrary1
{
    /// <summary>
    /// Window1.xaml の相互作用ロジック
    /// </summary>

    public partial class Window1 : Window
    {
        private ObservableCollection<string> messages = new ObservableCollection<string>();
        private ObservableCollection<LvList> ListView_List = new ObservableCollection<LvList>();

        public Window1()
        {
            InitializeComponent();

            ListBox1.ItemsSource = messages;
            ListView1.ItemsSource = ListView_List;
        }

        public void AddItemToList(string mess) // MAX君から来たやつ
        {
            messages.Add(mess); // 突っ込む 
        }

        public void Fill_ListView(bool MAXcheck, string MAXName, string MAXState) // MAX君から来たやつ
        {
            LvList item = new LvList { Check = MAXcheck, Name = MAXName, State = MAXState }; // 追加する項目を作成
            ListView_List.Add(item); // Listに項目を追加

        }

        public class LvList
        {
            public bool Check { get; set; }
            public string Name { get; set; }
            public string State { get; set; }
        }

    }




}
<Window x:Class="WpfControlLibrary1.Window1"
        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:WpfControlLibrary1"
        mc:Ignorable="d"
        Title="Window1" Height="450" Width="800">
    <Grid>
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFA9FFBD" Offset="0"/>
                <GradientStop Color="Black" Offset="1"/>
            </LinearGradientBrush>
        </Grid.Background>
        <Grid Margin="10,10,10,9.6">
            <Grid.RowDefinitions>
                <RowDefinition Height="12*"/>
                <RowDefinition Height="10*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="10*"/>
                <ColumnDefinition Width="5*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="Button" Content="Button" x:FieldModifier="public" Margin="30.2,0,30,10.4" Grid.Column="1" Height="39" VerticalAlignment="Bottom" Background="#FF64BF68" Grid.Row="1"/>
            <ListBox x:Name="ListBox1" x:FieldModifier="public" Margin="10,10,10,10.4"/>
            <ListView x:Name="ListView1" x:FieldModifier="public" Margin="10,10,9.8,10.4" Grid.Row="1">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Width="28">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox IsChecked="{Binding Check}" />
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="300" />
                        <GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="170"/>
                    </GridView>
                </ListView.View>
            </ListView>
        </Grid>
    </Grid>
</Window>
fn main =(
	dotnet.loadAssembly (getFilenamePath (getSourceFileName()) +@"WpfControlLibrary1.dll")
	global Form1 = dotnetObject "WpfControlLibrary1.Window1"
		
	Form1.topmost = true	
	Form1.Show()
		
	Form1.AddItemToList "test"
	Form1.Fill_ListView true "こんにちは" "OK!!"
		
	fn test =(
		Form1.AddItemToList "Test!!"
	)
		
	dotNet.addEventHandler Form1.button "Click" test
)

main()

動きました

MAXでアクセスしたいUI要素には x:FieldModifier=”public” を付けないとアクセスできません。
dotNet.addEventHandler WpfControlLibrary1.Window1 “Click” Fn で普通にイベントハンドラを追加できます。

dotNet.setLifetimeControl ******** #dotnetを実行するとMAX側にイベントハンドラを渡せるようです。これしないとgc()でメモリからハンドラが消える。

:おまけ
IL DASM便利です。