Civil3D开发者指南系列之二——创建WPF面板、导出当前图形设置

1. 创建一个标签样式对象

所有的civil3D对象标签都由标签样式管理,称之为 LabelStyle 。一个标签样式可以包含多个文本标签,符号标记、直线、记号和箭头。 下面的实例将创建一个点的标签样式:

public void CreatePointLabel()
{
    var id = civilDoc.Styles.LabelStyles.PointLabelStyles.LabelStyles.Add("UCDBIM");
}

2. 将命令集中在面板中

通过CivilTools命令调出面板

[CommandMethod("CivilTools")]
public void CivilTools()
{
    var ps = new PaletteSet("CIVIL 3D工具集", new Guid("63B8DB5B-10E4-4924-B8A2-A9CF9158E4F6"));
    ps.Style = PaletteSetStyles.ShowPropertiesMenu | PaletteSetStyles.ShowAutoHideButton |
               PaletteSetStyles.ShowCloseButton;
    ps.MinimumSize = new System.Drawing.Size(800,450);
    var pl = new Palette();
    pl.Content= new CivilWindow();
    ps.AddVisual("工具集", pl);
    ps.Visible = true;
}
<UserControl x:Class="Civil3DAPI.CivilWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:Civil3DAPI"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800" Name="Civil_3D小工具"
             Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button x:Name="bt00" Margin="8" Grid.Column="0" Click="Bt00_Click">创建点样式</Button>
        <Button x:Name="bt01" Margin="8" Grid.Column="0" Grid.Row="1" Click="Bt01_Click">获取线路设置</Button>
        <Button x:Name="bt02" Margin="8" Grid.Column="0" Grid.Row="2" Click="Bt02_Click">获取线路对象线型</Button>
        <Button x:Name="bt10" Margin="8" Grid.Column="1" Click="Button_Click">创建点标签样式</Button>
    </Grid>
</UserControl>
using System.Windows;
using System.Windows.Controls;

namespace Civil3DAPI
{
    /// <summary>
    ///     CivilWindow.xaml 的交互逻辑
    /// </summary>
    public partial class CivilWindow : UserControl
    {
        public CivilWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var cs = new CivilSample();
            cs.CreatePointLabel();
        }

        private void Bt00_Click(object sender, RoutedEventArgs e)
        {
            var cs = new CivilSample();
            cs.CreatePointStyle("UCD");
        }

        private void Bt01_Click(object sender, RoutedEventArgs e)
        {
            var cs = new CivilSample();
            cs.AlignmentSetting();
        }

        private void Bt02_Click(object sender, RoutedEventArgs e)
        {
            var cs = new CivilSample();
            cs.AlignmentTypeOption();
        }
    }
}

3. 导出当前文件设置

using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.Settings;
using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;

namespace Civil3DAPI
{
    public class CSSample
    {
        public Editor ed;
        public string file;
        public StringBuilder xml;

        public void ExportCommandSettings()
        {
            var sfd = new SaveFileDialog();
            sfd.Filter = "XML 文件|*.xml";
            sfd.DefaultExt = "xml";
            sfd.FileName = "CMD_settings.xml";
            sfd.Title = "导出command settings";
            if (sfd.ShowDialog() == DialogResult.OK)
                file = sfd.FileName;
            else
                return;

            var civilDoc = CivilApplication.ActiveDocument;
            var doc = Application.DocumentManager.MdiActiveDocument;
            var ed = doc.Editor;
            var db = doc.Database;
            xml = new StringBuilder();
            xml.Append("<CommandSettings>\n");
            Type[] types =
            {
                typeof(SettingsRoot)
            };
            var aeccdbmgd = typeof(CivilDocument).Module.Assembly;
            var types2 = aeccdbmgd.GetTypes();
            foreach (var t in types2)
                if (t.Name.Contains("SettingsCmd")
                    && (t.BaseType.Name.Contains("SettingsAmbient")
                        || t.BaseType.BaseType.Name.Contains("SettingsAmbient")))
                {
                    ed.WriteMessage("Command Setting found:" + t.Name + "\n");
                    xml.Append(string.Format("<CommandSetting name=\"{0}\">\n", t.Name));
                    try
                    {
                        var conInfo = t.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance,
                            null, types, null);
                        object[] s4 = {civilDoc.Settings};
                        var settingsAmbient = (SettingsAmbient) conInfo.Invoke(s4);
                        GetPropsOfObj(settingsAmbient, 2);
                    }
                    catch (Exception e)
                    {
                        ed.WriteMessage($"错误:\n{e.Message}\n{e.GetType()}");
                    }

                    xml.Append("</CommandSetting>\n");
                }

            xml.Append("</CommandSettings>\n");
            using (var sw = new StreamWriter(file))
            {
                sw.Write(xml.ToString());
                sw.Flush();
                sw.Close();
            }

            ed.WriteMessage("DONDE!\n");
        }

        private void GetPropsOfObj(object settingsAmbient, int v)
        {
            var space = " ".PadRight(v);
            var type = settingsAmbient.GetType();
            var properties = type.GetProperties(
                BindingFlags.Public | BindingFlags.Instance);
            foreach (var info in properties)
            {
                var obsoleteattri = info.GetCustomAttributes(
                    typeof(ObsoleteAttribute), true);
                if (obsoleteattri.Length > 0) continue;

                object prop = null;
                try
                {
                    prop = type.InvokeMember(info.Name, BindingFlags.GetProperty,
                        null, settingsAmbient, new object[0]);
                }
                catch (Exception e)
                {
                    ed.WriteMessage($"错误:{type.Name} {info.Name} {e.Message}\n{e.GetType()}\n");
                }

                if (prop.GetType().Name.Contains("Settings"))
                {
                    xml.Append(string.Format(space + "<Property name=\"{0}\">\n", info.Name));
                    GetPropsOfObj(prop, v + 3);
                    xml.Append(space + "</Property>\n");
                }
                else if (prop.GetType().Name.Contains("Property"))
                {
                    var propType = prop.GetType();
                    try
                    {
                        var val = propType.InvokeMember("Value", BindingFlags.GetProperty, null, prop, new object[0]);
                        var strvalue = val.ToString();
                        if (strvalue.Contains("<") || strvalue.Contains(">"))
                            strvalue = strvalue.Replace("<", "").Replace(">", "");

                        xml.Append(string.Format(space + "<Property name=\"{0}\" value=\"{1}\"/>\n", info.Name,
                            strvalue));
                    }
                    catch (Exception e)
                    {
                        ed.WriteMessage(
                            $"错误:{type.Name} {info.Name} {propType.Name}Value {e.Message}\n{e.GetType()}\n");
                    }
                }
                else
                {
                    ed.WriteMessage("Didn't process:{0}{1}\n",
                        info.Name, info.PropertyType.ToString());
                }
            }
        }
    }
}