Viso VSTO - ShapeAdded event not firing (sometimes)

人走茶凉 提交于 2019-12-24 20:18:05

问题


In my Add-in for Visio, I have set a handler for 'ShapeAdded'. This fired for the first 2 or 3 shapes that are added, but then just stop firing altogether.

Here's the basic outline of how my add-in functions:

  1. User adds shape to page
  2. On ShapeAdded, a form is displayed.
  3. User enters text in form, presses search button
  4. Call to stored Procedure (parameter = user text)
  5. Form's datagridview is populated with results.
  6. User double-clicks result row required.
  7. Form closes, selected value becomes shape text.

If I comment out my code after item (3) - then my event handler continues firing without issue. I can add new shapes all day long.

BUT - once I let code call the stored procedure (step 4), then that is where problems arise. Very specifically : da.Fill(dt) I may manage 1 to 6 shape adds, but sooner or later, the event just stops firing. (*update 8th Jan: Recordset size seems to affect the issue. When 1100 rows are returned each time, I manage to add around 6 shapes to my page. When 3 rows returned each time, I get to add up to 18 shapes before the events stop firing. That tells me there is something not 'clean' about the way I am handling my data calls - but I cannot see what it is !!)

I am totally baffled as to why calling the stored procedure would interfere with my event handler !?!? Especially without any error messages.

Has anyone any ideas whatsoever as to what I might be doing wrong ? Or even, ideas around how to debug this in a better manner ?

public partial class ThisAddIn
    {
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            Globals.ThisAddIn.Application.MarkerEvent += new Visio.EApplication_MarkerEventEventHandler(Application_MarkerEvent);
        }

        private void Application_MarkerEvent(Visio.Application visapp, int SequenceNum, string ContextString)
        {
            if (ContextString.Contains("soln=myApplication") && ContextString.Contains("/cmd=DocCreated"))
            {
                SetDocEvents();
            }
        }

        public void SetDocEvents()
        {
             Microsoft.Office.Interop.Visio.Document doc = Globals.ThisAddIn.Application.ActiveDocument;

            // set event handler
            try
            {
                doc.ShapeAdded += new Microsoft.Office.Interop.Visio.EDocument_ShapeAddedEventHandler(onShapeAdded);
            }
            catch (Exception err)
            {
                System.Diagnostics.Debug.WriteLine(err.Message);
                throw;
            }
        }

        private void onShapeAdded(Visio.Shape Shape)
        {
            Form_Entity fe = new Form_Entity(Shape.Text);
            fe.ShowDialog();
            fe.Dispose();
        }

    // ... other stuff
}

Form Code:

public partial class Form_Entity : Form
{
    public Int32 eid { get { return m_id; } }
    public string ename { get { return m_name; } }
    public string eabbr { get { return m_abbr; } }

    private Int32 m_id;
    private string m_name;
    private string m_abbr;

    public Form_Entity()
    {
        InitializeComponent();
    }
    public Form_Entity(String search)
    {
        InitializeComponent();
        txt_search.Text = search;
    }

    private void Cmd_Search_Click(object sender, EventArgs e)
    {
        String sample = txt_search.Text;

        DataTable dt = new DataTable();

SqlConnection myConn = new SqlConnection("Server=xxxxxxx;Database=xxxxxxxx;Trusted_Connection=True;");
        myConn.Open();
        SqlCommand myCmd = new SqlCommand("[dbo].[mySearch]", myConn);
        myCmd.Parameters.Add(new SqlParameter("@searchText", sample));
        myCmd.CommandType = CommandType.StoredProcedure;
        SqlDataAdapter da = new SqlDataAdapter(myCmd);
        da.Fill(dt);
        dataGridView1.DataSource = dt;

        myCmd.Dispose();
        myConn.Close();

    }
}

** Files for this project

  • Visual Studio Solution
  • T-SQL to create sample table/data.procedure
  • Viso Template
  • ReadMe.txt

http://www.netshed.co.uk/temp/Vis_Sample.zip


回答1:


I think the problem here is that you're not keeping the doc object in scope and Visio will stop reporting events for which there is no reference.

You can add a field (or property) as follows and then the reference and associated events should be maintained:

public partial class ThisAddIn
{
    private Visio.Document _targetDoc = null;

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        Application.MarkerEvent += Application_MarkerEvent;
    }

    public void SetDocEvents()
    {
        _targetDoc = Globals.ThisAddIn.Application.ActiveDocument;

        // set event handler
        try
        {
            _targetDoc.ShapeAdded += onShapeAdded;
        }
        catch (Exception err)
        {
            System.Diagnostics.Debug.WriteLine(err.Message);
            throw;
        }
    }


来源:https://stackoverflow.com/questions/48081736/viso-vsto-shapeadded-event-not-firing-sometimes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!