.NET6: 開發基於WPF的摩登三維工業軟體 (2)
在《.NET6: 開發基於WPF的摩登三維工業軟體 (1)》我們創建了一個”毛坯”介面,距離摩登還差一段距離。本文將對上一階段的成果進行深化,實現當下流行的暗黑風格UI。
1 設置暗黑主題
利用MergedDictionaries配置,在已有的通用風格基礎上添加Dark.Blue主題。程式碼如下:
App.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Fluent;Component/Themes/Generic.xaml" />
<ResourceDictionary Source="pack://application:,,,/Fluent;component/Themes/Themes/Dark.Blue.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
運行一下:
主題已經變成了暗黑模式。
2 給Button增加圖標
2.1 引入圖片
在項目目錄下增加Resources目錄,把circle.png複製到Resources目錄下。
在項目瀏覽器中把圖片添加到項目,選擇Resources目錄,右鍵菜單:
選擇Resources/circle.png
2.2 設置圖片屬性
選擇圖片,在屬性面板中設置:
- 複製到輸出目錄: 始終複製
- 生成操作:內容
按照上述步驟加入其他的圖片。
2.3 Ribbon Button中使用圖片
為Fluent:Button設置Icon屬性,引用圖片資源
<!--Tabs-->
<Fluent:RibbonTabItem Header="建模">
<Fluent:RibbonGroupBox Header="基本體" IsLauncherVisible="False">
<Fluent:Button Header="直線" Icon="/Resources/line.png" Size="Large"/>
<Fluent:Button Header="圓弧" Icon="/Resources/arc3pts.png" Size="Large"/>
<Fluent:Button Header="圓形" Icon="/Resources/circle.png" Size="Large"/>
</Fluent:RibbonGroupBox>
</Fluent:RibbonTabItem>
<Fluent:RibbonTabItem Header="設置">
</Fluent:RibbonTabItem>
運行一下:
3 增加Button響應消息
3.1 增加路由命令
定義RoutedCommand用於響應Button的點擊事件。
MainWindow.xaml.cs
public partial class MainWindow
{
// 定義路由命令
public static readonly RoutedCommand ExecuteCommand = new RoutedCommand("Rapid", typeof(MainWindow));
public MainWindow()
{
InitializeComponent();
// 綁定響應函數
CommandBindings.Add(new CommandBinding(ExecuteCommand, OnExecuteCommand));
}
private void RibbonWindow_Loaded(object sender, RoutedEventArgs e)
{
}
// 處理點擊命令
private void OnExecuteCommand(object sender, ExecutedRoutedEventArgs e)
{
}
}
3.2 XAML里綁定Button綁定事件
- Command: 綁定的命令
- CommandParameter: 命令參數
MainWindow.xaml
<Fluent:Button Header="直線" Icon="/Resources/line.png" Size="Large" Command="{x:Static local:MainWindow.ExecuteCommand}"
CommandParameter="line"/>
<Fluent:Button Header="圓弧" Icon="/Resources/arc3pts.png" Size="Large" Command="{x:Static local:MainWindow.ExecuteCommand}"
CommandParameter="arc"/>
<Fluent:Button Header="圓形" Icon="/Resources/circle.png" Size="Large" Command="{x:Static local:MainWindow.ExecuteCommand}"
CommandParameter="circle"/>
3.3 命令處理函數
MainWindow.xaml.cs
csharp // 處理點擊命令 private void OnExecuteCommand(object sender, ExecutedRoutedEventArgs e) { switch (e.Parameter.ToString()) { case "line": { var shape = SketchBuilder.MakeLine(new GPnt(0, 0, 0), new GPnt(10, 10, 0)); mView3d.ShowShape(shape, ColorTable.AliceBlue); } break; case "arc": { var shape = SketchBuilder.MakeArcOfCircle(new GPnt(0, 0, 0), new GPnt(10, 10, 0), new GPnt(5,15,0)); mView3d.ShowShape(shape, ColorTable.AliceBlue); } break; case "circle": { var shape = SketchBuilder.MakeCircle(new GPnt(0, 0, 0), 5, GP.DZ()); mView3d.ShowShape(shape, ColorTable.AliceBlue); } break; } }
運行一下,挨個Button點一遍:
4 綜合建模
愛心巧克力
一種實現方法:
- 由線生成愛心平面輪廓
- 輪廓填充成面
- 面拉伸成體
- 對體倒角
{
var arc1 = SketchBuilder.MakeArcOfCircle(new GPnt(0, 2, 0), new GPnt(10, 0, 0), new GPnt(5, 5, 0));
var arc2 = SketchBuilder.MakeArcOfCircle(new GPnt(0, 2, 0), new GPnt(-10, 0, 0), new GPnt(-5, 5, 0));
var bottomPt = new GPnt(0, -12, 0);
var line1 = SketchBuilder.MakeLine(new GPnt(-10, 0, 0), bottomPt);
var line2 = SketchBuilder.MakeLine(bottomPt, new GPnt(10, 0, 0));
var shapeList = new TopoShapeList();
shapeList.Add(arc1);
shapeList.Add(arc2);
shapeList.Add(line1);
shapeList.Add(line2);
var wire = SketchBuilder.MakeWire(shapeList);
var face = SketchBuilder.MakePlanarFace(wire);
var shape = FeatureTool.Extrude(face, 5, GP.DZ());
shape = FeatureTool.Fillet(shape, 1);
mView3d.ShowShape(shape, ColorTable.PaleVioletRed);
}
5 總結
本文通過簡潔的示例實現了暗黑風格的程式介面,為Ribbon增加Icon圖片,並通過WPF的命令路由機制實現了按鈕消息處理方法。最後,通過AnyCAD的建模API創建複雜的形狀:愛心巧克力。本文所有程式碼:Valentine’s Day
最後,祝天下所有的程式設計師情人節快樂!
var mesh = FontManager.Instance().CreateMesh("情人節快樂!");
var material = MeshPhongMaterial.Create("love-material");
material.SetColor(ColorTable.OrangeRed);
var shape = new PrimitiveSceneNode(mesh, material);
mView3d.ShowSceneNode(shape);