ArcGIS AddIN自动保存工具说明与源码

功能:实现ArcMap数据编辑过程中,按照设定的时间自动保存。

自动保存相关配置写入注册表,用户配置完自动保存相关设置后,之后每次打开编辑模式,自动启动自动保存逻辑。

界面如下:

配置项说明:选择“打开编辑,则自动保存”项,点击确定后,则每次打开编辑模式,则启动自动保存逻辑

选择“取消自动保存”项,则不启用自动保存逻辑。注意,安装了本工具后,若不想使用自动保存功能,需选择该项,并点击确定,取消自动保存逻辑。

“弹窗提示后保存”,选择该项后,每次自动保存时,会弹出如下提示框,用户点击确定后,则自动进行保存。点击暂不,则不进行保存。

右侧文本框将记录每次自动保存工作

使用建议:建议勾选“弹窗提示后保存”,好处:(1)在绘制较大图斑时,如果触发了自动保存,则绘制的草图丢失。使用弹窗模式时,弹窗提醒后,记得点击暂不,绘制完草图之后,再手工触发自动保存 (2)防止临时编辑内容误存

具体下载见:

ArcMap DayDreamInGIS 数据处理工具(裁剪工具/字段修改/要素合并/属性筛选/空间连接)版本更新说明_u012839776的博客-CSDN博客下载地址见百度网盘链接:https://pan.baidu.com/s/1ZSCxKrm3c4TReoxzJHdYOA提取码:vwgh——————————————————————————————————————————————————20200503 V1.0.12 字段修改工具中 日期类型Bug修复近期待更新:工具窗体修改为WPF使用注意事项:(0)欢迎大家提...https://blog.csdn.net/u012839776/article/details/105910588?spm=1001.2014.3001.5501源码

1.button部分

button部分代码比较简单,主要实现弹出自动保存对话框。

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Editor;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System.Windows;

namespace DayDreamInGISTool.AutoSave
{
    public class btnAutoSave : ESRI.ArcGIS.Desktop.AddIns.Button
    {
        string toolnm = "AutoSave";
        AutoSaveWPF awp = null;
        public btnAutoSave()
        {
            
        }

        protected override void OnClick()
        {
            if (awp == null)
            {
                awp = new AutoSaveWPF();
            }

            awp.ShowDialog();

            //if (awp.ShowDialog().Value)
            //{
            //    //RO.interval = awp.Interval;
            //    //RO.MsgSave = awp.MsgSave;
            //    //RO.tp = awp.Tp;
            //}
        }

        protected override void OnUpdate()
        {
            
        }
    }
}

2.界面逻辑

界面使用WPF技术制作

界面源码

<Window x:Class="DayDreamInGISTool.AutoSave.AutoSaveWPF"
             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" 
             mc:Ignorable="d" Activated="Window_Activated_1"     
        Title="自动保存设置" WindowStartupLocation="CenterScreen"
             Width="300" Height="200" ResizeMode="NoResize">
    <Grid>
        <RadioButton Content="打开编辑,则自动保存" Name="rdb_forever" HorizontalAlignment="Left" Margin="45,17,0,0" VerticalAlignment="Top"/>
        <RadioButton Name="rdb_cancel" Content="取消自动保存" HorizontalAlignment="Left" Margin="45,44,0,0" VerticalAlignment="Top"/>
        <Button Name="btnOK" Content="确定" HorizontalAlignment="Left" Margin="91,133,0,0" VerticalAlignment="Top" Width="85" Height="27" Click="btnOK_Click"/>
        <TextBox Name="txt_interval" HorizontalAlignment="Left" Height="23" Margin="91,105,0,0" TextWrapping="Wrap" Text="5" VerticalAlignment="Top" Width="180"/>
        <Label x:Name="label" Content="间隔(分钟)" HorizontalAlignment="Left" Margin="20,101,0,0" VerticalAlignment="Top"/>
        <CheckBox Name="chkMsgSave" Content="弹窗提示后保存" HorizontalAlignment="Left" Margin="45,74,0,0" VerticalAlignment="Top"/>
        <Button Content=">>" HorizontalAlignment="Left" Name="btnShowDetail" Margin="224,133,0,0" VerticalAlignment="Top" Width="47" Height="27" Click="btnShowDetail_Click"/>
        <RichTextBox IsReadOnly="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto" Name="rct" HorizontalAlignment="Left" Height="150" Margin="300,10,0,0" VerticalAlignment="Top" Width="284">
            <FlowDocument>
                <Paragraph>
                    <Run Text="保存记录"/>
                </Paragraph>
            </FlowDocument>
        </RichTextBox>

    </Grid>
</Window>

界面逻辑源码

using System;
using System.Windows;
using System.Collections.Generic;
using System.Windows.Documents;
using System.ComponentModel;

namespace DayDreamInGISTool.AutoSave
{
    /// <summary>
    /// AutoSaveWPF.xaml 的交互逻辑
    /// </summary>
    public partial class AutoSaveWPF : Window
    {
        string toolnm = "AutoSave";
        public AutoSaveWPF()
        {
            InitializeComponent();
            //从注册表中读取值
            //自动保存间隔
            object obj = GISCommonHelper.esriSystemHelper.getValueFromReg2(toolnm, "interval");
            try
            {
                this.Interval = (int)obj;
            }
            catch (Exception ex)
            {
                this.Interval = 5;
            }
            this.txt_interval.Text = Interval.ToString();

            //自动保存类型
            obj = GISCommonHelper.esriSystemHelper.getValueFromReg2(toolnm, "SaveTp");
            try
            {
                this.Tp = obj.ToString();
            }
            catch (Exception ex)
            {
                this.Tp = "2";
            }

            if (Tp == "1")
                this.rdb_forever.IsChecked = true;
            else
                this.rdb_cancel.IsChecked = true;

            //是否只提示,不保存
            bool msgsave = true;
            try
            {
                string bs = GISCommonHelper.esriSystemHelper.getValueFromReg2(toolnm, "MsgSave").ToString();
                if (bs == "False")
                {
                    msgsave = false;
                }
                else if (bs == "True")
                {
                    msgsave = true;
                }
                else
                    msgsave = false;
            }
            catch (Exception ex)
            {
                msgsave = true;
            }

            this.chkMsgSave.IsChecked = msgsave;

        }

        /// <summary>
        /// 自动保存间隔
        /// </summary>
        public int Interval { get; set; }
        /// <summary>
        /// 类型 1 写入注册表,永久保存 2.取消自动保存
        /// </summary>
        public string Tp { get; set; }

        public bool MsgSave { get; set; }

        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            if (rdb_forever.IsChecked.Value)
            {
                //写入注册表
                Tp = "1";
            }

            if (rdb_cancel.IsChecked.Value)
            {
                //取消自动保存
                Tp = "2";
            }

            int interval = 5;
            //Interval = 5;
            if (!int.TryParse(txt_interval.Text, out interval))
            {
                MessageBox.Show("保存间隔须为整数");
                return;
            }
            Interval = interval;
            if (this.chkMsgSave.IsChecked.Value)
                MsgSave = this.chkMsgSave.IsChecked.Value;
            else
            {
                MsgSave = false;
            }

            GISCommonHelper.esriSystemHelper.setValueToReg2(toolnm, new KeyValuePair<string, object>("SaveTp", Tp));
            GISCommonHelper.esriSystemHelper.setValueToReg2(toolnm, new System.Collections.Generic.KeyValuePair<string, object>("MsgSave", MsgSave));
            GISCommonHelper.esriSystemHelper.setValueToReg2(toolnm, new KeyValuePair<string, object>("Interval", Interval));

            this.DialogResult = true;
        }

        private void btnShowDetail_Click(object sender, RoutedEventArgs e)
        {
            if (btnShowDetail.Content == "<<")
            {
                this.Width = 300;
                btnShowDetail.Content = ">>";
            }
            else
            {
                this.Width = 600;
                btnShowDetail.Content = ">>";
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            e.Cancel = true;  // cancels the window close    
            this.Hide();      // Programmatically hides the window
        }

        private void Window_Activated_1(object sender, EventArgs e)
        {
            string msg = AutoSaveEditorExt.sb.ToString();
            if (!string.IsNullOrEmpty(msg))
            {
                Run run = new Run(msg);
                Paragraph p = new Paragraph();
                p.Inlines.Add(run);
                this.rct.Document.Blocks.Add(p);

                //clear
                AutoSaveEditorExt.sb.Clear();
            }
            this.rct.ScrollToEnd();
        }
    }
}

3.编辑器扩展源码

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Editor;
using System.Timers;
using System.Windows;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

namespace DayDreamInGISTool.AutoSave
{
    /// <summary>
    /// AutoSaveEditorExt class implementing custom ESRI Editor Extension functionalities.
    /// </summary>
    public class AutoSaveEditorExt : ESRI.ArcGIS.Desktop.AddIns.Extension
    {
        /// <summary>
        /// 1 自动保存 2取消自动保存
        /// </summary>
        //string tp = "1";
        //bool msgsave = true;
        //int interval = 5;
        string toolnm = "AutoSave";
        int mnt = 30;
        public AutoSaveEditorExt()
        {
        }

        public static StringBuilder sb = new StringBuilder();

        Timer auto_save_timer = new Timer();
        string strTime;

        protected override void OnStartup()
        {
            IEditor theEditor = ArcMap.Editor;
            
            Events.OnStartEditing += new IEditEvents_OnStartEditingEventHandler(Events_OnStartEditing);
            Events.OnStopEditing += new IEditEvents_OnStopEditingEventHandler(Events_OnStopEditing);
        }

        protected override void OnShutdown()
        {
        }

        #region Editor Events

        #region Shortcut properties to the various editor event interfaces
        private IEditEvents_Event Events
        {
            get { return ArcMap.Editor as IEditEvents_Event; }
        }
        private IEditEvents2_Event Events2
        {
            get { return ArcMap.Editor as IEditEvents2_Event; }
        }
        private IEditEvents3_Event Events3
        {
            get { return ArcMap.Editor as IEditEvents3_Event; }
        }
        private IEditEvents4_Event Events4
        {
            get { return ArcMap.Editor as IEditEvents4_Event; }
        }
        #endregion

        void WireEditorEvents()
        {
            //
            //  TODO: Sample code demonstrating editor event wiring
            //
            Events.OnCurrentTaskChanged += delegate
            {
                if (ArcMap.Editor.CurrentTask != null)
                    System.Diagnostics.Debug.WriteLine(ArcMap.Editor.CurrentTask.Name);
            };
            Events2.BeforeStopEditing += delegate(bool save) { OnBeforeStopEditing(save); };
            
        }

        void OnBeforeStopEditing(bool save)
        {
        }

        void Events_OnStartEditing() 
        {
            //在此处启动自动保存的代码
            initial();
            this.auto_save_timer.Start();

            try 
            {
                auto_save_timer.Elapsed -= auto_save_timer_Elapsed;                
            }
            catch(Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }


            auto_save_timer.Elapsed += auto_save_timer_Elapsed;
            
            auto_save_timer.Interval = RO.interval* mnt * 1000;
        }


        void auto_save_timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString());
            initial();  //每隔一段时间,从注册表获取值
            if (RO.tp == "1")
            {
                //实现自动保存
                if (ArcMap.Editor.HasEdits())
                {
                    string tag = "autosave" + DateTime.Now.ToLongTimeString();

                    sb.AppendLine();
                    AutoSaveEditorExt.sb.Append("开始启动自动保存" + DateTime.Now.ToShortTimeString());

                    if (RO.MsgSave)
                    {
                        this.auto_save_timer.Stop();
                        IMessageDialog msgDlg = new MessageDialogClass();

                        IEditor pEditor = ArcMap.Editor;
                        IEditTask ct = pEditor.CurrentTask;
                        //IEditSketch pESketch = pEditor as IEditSketch;
                        //if (pESketch.Geometry == null) 
                        //{
                        //    System.Diagnostics.Debug.WriteLine("sketch 无geometry");
                        
                        //}
                        //else
                        //{
                        //    System.Diagnostics.Debug.WriteLine("sketch 无geometry");
                        //}
                        //if (ct != null)
                        //{
                        //    //存在编辑任务时,则不保存
                        //    AutoSaveEditorExt.sb.Append("-->编辑任务执行中,本次自动保存取消");
                        //    System.Diagnostics.Debug.WriteLine(ct.Name);
                        //    this.auto_save_timer.Start();

                        //    return;
                        //}
                        if (false) { }
                        else
                        {
                            //mdshow = true;
                            bool re = msgDlg.DoModal("自动保存提示?", "是否保存?", "自动保存", "暂不", ArcMap.Application.hWnd);
                            if (re)
                            {
                                ArcMap.Editor.StopOperation(tag);
                                save_edits();
                                //mdshow = false;
                                System.Diagnostics.Debug.WriteLine("保存后,是否存在未保存的:" + ArcMap.Editor.HasEdits());
                                AutoSaveEditorExt.sb.Append("-->成功");

                            }
                            else
                            {
                                //mdshow = false;
                                AutoSaveEditorExt.sb.Append("-->取消");

                            }
                            this.auto_save_timer.Start();
                        }
                        
                        
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("自动保存中...");
                        ArcMap.Editor.StopOperation(tag);
                        save_edits();
                        AutoSaveEditorExt.sb.Append("-->成功");
                    }

                }
            }
        }

        private void save_edits() 
        {
            IEditor pEditor = ArcMap.Editor;
            IWorkspace pws = pEditor.EditWorkspace;
            pEditor.StopEditing(true);  //保存之后再打开编辑
            pEditor.StartEditing(pws);
        }

        void Events_OnStopEditing(bool Save)
        {
            //结束保存 关闭计时器
            this.auto_save_timer.Stop();
        }
        #endregion

        /// <summary>
        /// 从注册表获取值到静态类中
        /// </summary>
        /// <returns></returns>
        private bool initial()
        {
            try
            {
                string tp = GISCommonHelper.esriSystemHelper.getValueFromReg2(toolnm, "SaveTp").ToString();
                bool msgsave = false;
                var str=GISCommonHelper.esriSystemHelper.getValueFromReg2(toolnm, "MsgSave").ToString();
                if (str.ToLower() == "true") 
                {
                    msgsave = true;
                }
                int interval = (int)GISCommonHelper.esriSystemHelper.getValueFromReg2(toolnm, "Interval");
                RO.tp = tp;
                RO.MsgSave = msgsave;
                RO.interval = interval;
                if (this.auto_save_timer.Enabled)
                {
                    this.auto_save_timer.Interval = RO.interval * mnt * 1000;
                }
                return true;
            }
            catch
            {
                System.Diagnostics.Debug.WriteLine("自动保存启动失败!");
                RO.tp = "2";
                RO.interval = 5;  //默认5分钟
                if (this.auto_save_timer.Enabled)
                {
                    this.auto_save_timer.Interval = RO.interval * mnt * 1000;
                }
                return false;
            }
        }
    }

}

4.其他

界面参数存储对象:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DayDreamInGISTool.AutoSave
{
    public class RO
    {
        public static string tp = "2";
        public static bool MsgSave = true;
        public static int interval = 5;
    }
}

注册表操作方法:

/// <summary>
        /// 从注册表获取值
        /// </summary>
        /// <param name="toolname">工具名称</param>
        /// <param name="key">值名称</param>
        /// <returns></returns>
        public static IMemoryBlobStream getValueFromReg(string toolname, string key)
        {
            try
            {
                RegistryKey rootkey = Registry.CurrentUser;
                RegistryKey sftkey = rootkey.OpenSubKey("software", true);
                RegistryKey llcsft = sftkey.OpenSubKey("llcSft");
                RegistryKey AddinCfg = llcsft.OpenSubKey("AddInConfig");
                RegistryKey AddInName = AddinCfg.OpenSubKey(toolname);
                byte[] tmp = (byte[])AddInName.GetValue(key);
                return CreateMemoryStreamFromByte(tmp);
            }
            catch (System.Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// 从注册表获取值
        /// </summary>
        /// <param name="toolname"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object getValueFromReg2(string toolname, string key) 
        {
            try
            {
                RegistryKey rootkey = Registry.CurrentUser;
                RegistryKey sftkey = rootkey.OpenSubKey("software", true);
                RegistryKey llcsft = sftkey.OpenSubKey("llcSft");
                RegistryKey AddinCfg = llcsft.OpenSubKey("AddInConfig");
                RegistryKey AddInName = AddinCfg.OpenSubKey(toolname);
                return AddInName.GetValue(key);
            }
            catch (System.Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// 写入注册表
        /// </summary>
        /// <param name="toolName">工具名称</param>
        /// <param name="pm">键值</param>
        /// <returns></returns>
        public static bool setValueToReg(string toolName, KeyValuePair<string, object> pm)
        {
            try
            {
                RegistryKey rootkey = Registry.CurrentUser;
                RegistryKey sftkey = rootkey.OpenSubKey("software", true);
                RegistryKey llcsft = sftkey.CreateSubKey("llcSft");
                RegistryKey AddinCfg = llcsft.CreateSubKey("AddInConfig");
                RegistryKey AddInName = AddinCfg.CreateSubKey(toolName);
                AddInName.SetValue(pm.Key, CreateByteFromObjData(pm.Value), RegistryValueKind.Binary);
            }
            catch (System.Exception ex)
            {
                return false;
            }
            return true;
        }

        public static bool setValueToReg2(string toolName, KeyValuePair<string, object> pm)
        {
            try
            {
                RegistryKey rootkey = Registry.CurrentUser;
                RegistryKey sftkey = rootkey.OpenSubKey("software", true);
                RegistryKey llcsft = sftkey.CreateSubKey("llcSft");
                RegistryKey AddinCfg = llcsft.CreateSubKey("AddInConfig");
                RegistryKey AddInName = AddinCfg.CreateSubKey(toolName);
                AddInName.SetValue(pm.Key, pm.Value);
            }
            catch (System.Exception ex)
            {
                return false;
            }
            return true;
        }

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值