Maxscript interacts with WPF

0 votes

I used WPF to write an interface that implements the function of buttons to switch between different pages, and usercontrol for subpages. When calling this wpf-written interface library in MaxScript, the events are written in MaxScript. Events are useful when the widgets on my main page are bound in MaxScript. But the controls I defined in the subpage have no effect. But when I define Form1.MainContent.Content = Form2 -- set the subpage as the main content

The subpage's controls are also reactive when I first start, when I switch pages. Is there a response to the button event of the subpage, what is the reason, and how to solve it
This is the code for the main page

  1. <Window
  2. x:Class="页面切换测试.MainWindow"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  6. xmlns:local="clr-namespace:页面切换测试"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. Title="MainWindow"
  9. Width="250"
  10. Height="60"
  11. MinHeight="60"
  12. MaxHeight="1500"
  13. ResizeMode="NoResize"
  14. SizeChanged="MainWindow_SizeChanged"
  15. SizeToContent="Height"
  16. mc:Ignorable="d">
  17. <!-- SizeToContent="Height" -->
  18. <Grid>
  19.  
  20. <!-- 使用 Grid 布局,定义两行:第一行用于按钮,第二行用于内容 -->
  21. <Grid.RowDefinitions>
  22. <RowDefinition Height="Auto" />
  23. <!-- 第一行高度自动调整 -->
  24. <RowDefinition Height="*" />
  25. <!-- 第二行占据剩余空间 -->
  26. </Grid.RowDefinitions>
  27. <!-- Buttons to switch between UserControls -->
  28. <StackPanel
  29. Margin="10"
  30. HorizontalAlignment="Center"
  31. VerticalAlignment="Top"
  32. Orientation="Horizontal">
  33. <Button
  34. Width="100"
  35. Click="Button_Click"
  36. Content="Page 1" />
  37. <Button
  38. Width="100"
  39. Click="Button_Click"
  40. Content="Page 2" />
  41. <Button
  42. x:Name="btn1"
  43. Width="auto"
  44. x:FieldModifier="public"
  45. Content="测试" />
  46. <!-- Add more buttons for additional pages as needed -->
  47. </StackPanel>
  48.  
  49. <!-- 内容区域 -->
  50. <ContentControl
  51. x:Name="MainContent"
  52. Grid.Row="1"
  53. MinHeight="{Binding ElementName=MainWindow, Path=MinHeight}"
  54. MaxHeight="{Binding ElementName=MainWindow, Path=MaxHeight}"
  55. Margin="10"
  56. HorizontalAlignment="Stretch"
  57. VerticalAlignment="Stretch"
  58. x:FieldModifier="public" />
  59. </Grid>
  60.  
  61. </Window>
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;
  14.  
  15. namespace 页面切换测试
  16. {
  17. /// <summary>
  18. /// MainWindow.xaml 的交互逻辑
  19. /// </summary>
  20. public partial class MainWindow : Window
  21. {
  22. private UserControl currentPage;
  23. private Dictionary<string, UserControl> pageCache = new Dictionary<string, UserControl>();
  24. public MainWindow()
  25. {
  26. InitializeComponent();
  27. SwitchToPage("Page 1");
  28. }
  29.  
  30. public void Button_Click(object sender, RoutedEventArgs e)
  31. {
  32. Button btn = (Button)sender;
  33.  
  34. switch (btn.Content.ToString())
  35. {
  36. case "Page 1":
  37. SwitchToPage("Page 1");
  38.  
  39. break;
  40. case "Page 2":
  41. SwitchToPage("Page 2");
  42. break;
  43. // Add cases for additional pages as needed
  44. }
  45.  
  46. }
  47.  
  48.  
  49. public void SwitchToPage(string pageName)
  50. {
  51.  
  52. if (!pageCache.ContainsKey(pageName))
  53. {
  54. switch (pageName)
  55. {
  56. case "Page 1":
  57. pageCache[pageName] = new Page1();
  58.  
  59. break;
  60. case "Page 2":
  61. pageCache[pageName] = new Page2();
  62. break;
  63. // Add cases for additional pages as needed
  64. }
  65. }
  66.  
  67.  
  68. // 强制重新计算布局
  69. // MainContent.InvalidateArrange();
  70. // MainContent.InvalidateMeasure();
  71.  
  72.  
  73. // 订阅 SizeChanged 事件,确保在窗口大小变化时调整高度
  74. // this.SizeChanged += MainWindow_SizeChanged;
  75.  
  76. // 调整窗口高度
  77. AdjustWindowHeight();
  78. currentPage = pageCache[pageName];
  79. MainContent.Content = currentPage;
  80. //AttachEventHandlers(currentPage);
  81. }
  82.  
  83. //private void AttachEventHandlers(UserControl page)
  84. //{
  85. // // 解除之前的事件绑定
  86. // var oldButton = currentPage?.FindName("siyou") as Button;
  87. // if (oldButton != null)
  88. // {
  89. // oldButton.Click -= HandleButtonClick;
  90. // }
  91.  
  92. // // 绑定新的事件处理程序
  93. // var newButton = page.FindName("siyou") as Button;
  94. // if (newButton != null)
  95. // {
  96. // newButton.Click += HandleButtonClick;
  97. // }
  98. //}
  99.  
  100. //private void MainContent_LayoutUpdated(object sender, EventArgs e)
  101. //{
  102. // // 取消订阅 LayoutUpdated 事件,避免多次触发
  103. // MainContent.LayoutUpdated -= MainContent_LayoutUpdated;
  104.  
  105. // // 调整窗口高度
  106. // AdjustWindowHeight();
  107. //}
  108. private void AdjustWindowHeight()
  109. {
  110. double minHeight = this.MinHeight;
  111. double maxHeight = this.MaxHeight;
  112.  
  113. // 使用 Dispatcher 延迟调整窗口高度,确保 ActualHeight 已经计算完成
  114. this.Dispatcher.BeginInvoke(new Action(() =>
  115. {
  116. double contentHeight = MainContent.ActualHeight;
  117. // System.Diagnostics.Debug.WriteLine($"ContentHeight: {contentHeight}");
  118.  
  119. if (contentHeight > 0 && contentHeight < maxHeight)
  120. {
  121. this.Height = Math.Max(contentHeight + 50, minHeight); // 确保高度不低于 MinHeight
  122. }
  123. else if (contentHeight >= maxHeight)
  124. {
  125. // 如果内容高度超过最大高度,保持窗口高度为最大值
  126. this.Height = maxHeight;
  127. }
  128. else
  129. {
  130. // 如果内容高度小于最小高度,保持窗口高度为最小值
  131. this.Height = minHeight;
  132. }
  133. }), System.Windows.Threading.DispatcherPriority.Render);
  134. }
  135.  
  136. private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
  137. {
  138. // this.SizeToContent = SizeToContent.Manual;
  139. // this.SizeToContent = SizeToContent.Manual;
  140. AdjustWindowHeight();
  141. }
  142. }
  143. }

这是子页面的界面和事件代码

  1. <UserControl
  2. x:Class="页面切换测试.Page1"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  6. xmlns:local="clr-namespace:页面切换测试"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. d:DesignHeight="250"
  9. d:DesignWidth="250"
  10. mc:Ignorable="d">
  11. <Grid>
  12. <Button
  13. x:Name="siyou"
  14. HorizontalAlignment="Center"
  15. VerticalAlignment="Center"
  16. x:FieldModifier="public"
  17. Content="这是墙体页面"
  18. FontSize="24" />
  19. </Grid>
  20. </UserControl>
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Shapes;
  13. //using ManagedServices;
  14. namespace 页面切换测试
  15. {
  16. /// <summary>
  17. /// Page1.xaml 的交互逻辑
  18. /// </summary>
  19. public partial class Page1 : UserControl
  20. {
  21. public Page1()
  22. {
  23. InitializeComponent();
  24.  
  25. }
  26.  
  27. //private void siyou_Click(object sender, RoutedEventArgs e)
  28. //{
  29. // ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand("print \"Hello from MaxScript!\"")
  30. //}
  31. }
  32. }

这里是maxscript调用wpf程序的代码

  1. fn main =
  2. (
  3. -- 加载程序集
  4. dotnet.loadAssembly (getFilenamePath (getSourceFileName()) + @"页面切换测试.dll")
  5.  
  6. global Form1 = dotnetObject "页面切换测试.MainWindow"
  7. global Form2 = dotnetObject "页面切换测试.Page1" -- 子页面对象
  8.  
  9. -- 切换到子页面
  10. -- local mainContent = Form1.FindName "MainContent"
  11.  
  12.  
  13. Form1.MainContent.Content = Form2 -- 设置子页面为主内容
  14. dataContext = Form1.DataContext
  15. Form1.Show()
  16.  
  17. (dotnetobject "System.Windows.Interop.WindowInteropHelper" Form1).Owner = dotnetobject "IntPtr" (windows.GetMAXHWND())
  18.  
  19.  
  20.  
  21. )
  22.  
  23. fn handleButtonClick sender args =
  24. (
  25. -- 处理子页面按钮点击事件
  26. messageBox "子页面按钮被点击!"
  27. )
  28.  
  29. fn handleButtonClick1 sender args =
  30. (
  31. -- 处理主页面按钮点击事件
  32. messageBox "主页面按钮被点击!"
  33. )
  34. -- fn startFocus arg =
  35. -- (
  36. -- enableAccelerators = false
  37. -- )
  38. --
  39. -- fn stopFocus arg =
  40. -- (
  41. -- enableAccelerators = true
  42. -- )
  43.  
  44. fn setupEventHandlers =
  45. (
  46. -- 主页面按钮事件绑定
  47. -- local button1 = Form1.FindName "btn1"
  48. -- if button1 != undefined do
  49. -- (
  50.  
  51. dotNet.addEventHandler Form1.btn1 "Click" handleButtonClick1
  52. -- )
  53. -- else
  54. -- (
  55. -- print "Main button not found!"
  56. -- )
  57.  
  58. -- 子页面按钮事件绑定
  59. -- local button = Form2.FindName "siyou"
  60.  
  61.  
  62. dotNet.addEventHandler Form2.siyou "Click" handleButtonClick
  63. dotNet.addEventHandler Form1 "GotFocus" startFocus
  64. dotNet.addEventHandler Form1 "LostFocus" stopFocus
  65.  
  66. -- else
  67. -- (
  68. -- print "Child button not found!"
  69. -- )
  70.  
  71. -- 设置生命周期控制
  72. -- dotNet.setLifetimeControl button #dotNet
  73. dotNet.setLifetimeControl Form2.siyou #dotNet
  74. dotNet.setLifetimeControl Form1 #dotNet
  75. dotNet.setLifetimeControl Form2 #dotNet
  76. )
  77.  
  78.  
  79. main()
  80. setupEventHandlers()

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
AEI's picture

不要用ms写控件本身的功能,所有控件的实现由c#实现,与m

不要用ms写控件本身的功能,所有控件的实现由c#实现,与max交互由公共参数和公开方法实现,不会sdk时通过预先传递参数供控件使用,比如max主题颜色传给公共参数,控件实例化时读取公共参数,会sdk后通过sdk获取即可

Automatic Efficient Intelligent

We change the work state

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.