[C#] How to Properly Call "Page.FormulaChanged" from a Ribbon's Toggle Button

Started by Xenova, July 08, 2015, 05:55:27 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Xenova

Hi all,

       I'm a beginner in Visio programming. I have tried my best efforts to look for solution for this question before posting.
 
        A toggle button is created in the Visio's Ribbon. The purpose is 1) when toggle_button is checked = event listening is activated; 2) when toggle_button is unchecked = event listening is deactivated.

The button calls for a custom method called "FormulaChangeNotifier":
   
Quotevoid toggleButton_autoUpdateBNet_Click(object sender, RibbonControlEventArgs e)
        {
            VisioEventMonitoring cellMon = new VisioEventMonitoring();
            cellMon.FormulaChangeNotifier();
        }

Content of "FormulaChangeNotifier" method:
Quotepublic void FormulaChangeNotifier()
        {
            Visio.Page monPage = Globals.ThisAddIn.Application.ActivePage;
            monPage.FormulaChanged += new Visio.EPage_FormulaChangedEventHandler(onCellChanged);

Then i have "onCellChange" method to use the changed cell's information to execute computation i need:
Quoteprivate void onCellChanged(Visio.Cell cell)
        {
                 //My computation code using the "cell"
}

If i use the ABOVE implementation, it only detects the formula change ONCE (One and One Time) only until user clicks on the Toggle Button again. However, if i change the call method in the button to the following, Visio will go into a infinite loop.

Quotevoid toggleButton_autoUpdateBNet_Click(object sender, RibbonControlEventArgs e)
        {
            VisioEventMonitoring cellMon = new VisioEventMonitoring();
            cellMon.FormulaChangeNotifier(BnClass);

            while (toggleButton_autoUpdateBNet.Checked == true)
            {
                cellMon.FormulaChangeNotifier(BnClass);
            }
        }


Thanks in advance.

JuneTheSecond

Quote

            while (toggleButton_autoUpdateBNet.Checked == true)
            {
                cellMon.FormulaChangeNotifier(BnClass);
            }

I am not a programmer, but I have simple questions.
Why do you use while sentence than if sentence?
Did you monitor the value of "toggleButton_autoUpdateBNet.Checked"?
Is it really changed?
If "toggleButton_autoUpdateBNet.Checked" has only 2 values True or False,
I think you don't need "== true".
Best Regards,

Junichi Yoda
http://june.minibird.jp/

Xenova

Quote from: JuneTheSecond on July 09, 2015, 11:16:32 PM
Quote

            while (toggleButton_autoUpdateBNet.Checked == true)
            {
                cellMon.FormulaChangeNotifier(BnClass);
            }

I am not a programmer, but I have simple questions.
Why do you use while sentence than if sentence?
Did you monitor the value of "toggleButton_autoUpdateBNet.Checked"?
Is it really changed?
If "toggleButton_autoUpdateBNet.Checked" has only 2 values True or False,
I think you don't need "== true".

Hi Junichi Yoda,

        Thanks for your reply. The toggleButton is meant to be merely a switch to decide whether the event monitoring should be on or off.
        The event monitored is any change to the Formula of any Cell on that page.  --> "monPage.FormulaChanged += new Visio.EPage_FormulaChangedEventHandler(onCellChanged);"
        I tried both "while" and "if" statement. "while" statement will result in an infinite loop, whereas "if" statement as shown as below, also got its issue.

Quotevoid toggleButton_autoUpdateBNet_Click(object sender, RibbonControlEventArgs e)
        {
            VisioEventMonitoring cellMon = new VisioEventMonitoring();
            cellMon.FormulaChangeNotifier(BnClass);

            if(toggleButton_autoUpdateBNet.Checked == true)
            {
                cellMon.FormulaChangeNotifier();
            }
        }

Such statement will call for the FormulaChangeNotifier TWICE, using even users only change the formula on the page ONCE. Besides, using "IF" statement can't be used (maybe just me) to continuously monitoring the formula changed event as long as the button is checked.


JuneTheSecond

Thank you for your reply.
May I have one more simple question about " VisioEventMonitoring cellMon = new VisioEventMonitoring();"
Where can I find any link to VisioEventMonitoring?
Best Regards,

Junichi Yoda
http://june.minibird.jp/

JuneTheSecond

I am using Visio 2013.
And I use Visual Studio Comunity 2013 with Office Developer Tools for Visual Studio 2013, both are free version.
I wrote a C# code on Ribbon.cs with literary trial and errors, but it works well.
Here is not a line like a VisioEventMonitoring.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using Visio = Microsoft.Office.Interop.Visio;
using System.Windows.Forms;
namespace VisioAddIn12
{
    public partial class Ribbon1
    {
        private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
        {
        }

        private void toggleButton1_Click(object sender, RibbonControlEventArgs e)
        {
                        Visio.Page visPage = Globals.ThisAddIn.Application.ActivePage;
            if (toggleButton1.Checked)
            {
                toggleButton1.Label = "Page Formula Changed Event On";
                visPage.FormulaChanged += new Visio.EPage_FormulaChangedEventHandler(Page_FormulaChanged);
            }
            else
            {
                toggleButton1.Label = "No Events";
                visPage.FormulaChanged -= new Visio.EPage_FormulaChangedEventHandler(Page_FormulaChanged);
            }
        }

        private void Page_FormulaChanged(Visio.Cell cell)
        {
            MessageBox.Show(cell.Shape.Name + " Cell " + cell.Name + " formula changed to " + cell.Formula + " .");

        }
    }
}



And here is a short video in YouTube.
https://youtu.be/pU7uPc84KzQ
Best Regards,

Junichi Yoda
http://june.minibird.jp/

Xenova

Hi Junichi Yoda San,

       Really thank you very much for your time and effort in putting up the video and the codes.
       It works!

       The issue that i have is due to my codes. If i remove the part started from //REMOVE FROM HERE UNTIL THE END, the codes will work perfectly. However, if i keep these lines of codes, the method "onFormulaChanged" will only executed once (the formula changes will trigger the event correctly and run the codes within "onFormulaChanged". Any changes to the formula on that page after that will not trigger the method anymore.
   
       I will try to find out what is causing the issue and report it here. Or if anyone who spot the cause of the problem in the codes can also let us know.
       Once again, thank you for the help! :D


Quoteprivate void toggleButton_autoUpdateBNet_Click_1(object sender, RibbonControlEventArgs e)
        {
           
            if (toggleButton_autoUpdateBNet.Checked)
            {
                Globals.ThisAddIn.Application.ActivePage.FormulaChanged += new Visio.EPage_FormulaChangedEventHandler(onFormulaChanged);

            }
            else
            {
                Globals.ThisAddIn.Application.ActivePage.FormulaChanged -= new Visio.EPage_FormulaChangedEventHandler(onFormulaChanged);
            }
        }

        private void onFormulaChanged(Visio.Cell cell)
        {
            MessageBox.Show(cell.Shape.Name + " Cell " + cell.Name + " formula changed to " + cell.Formula + " .");

            //REMOVE FROM HERE UNTIL THE END
            //if only the call changed is involving these two rows
            if (cell.Name == "Prop.Increase" || cell.Name == "Prop.Decrease")
            {
                //Get the new Probability entered by user (Result INT)
                int newPropInt = cell.get_ResultInt(Visio.VisUnitCodes.visInches, 0);
                double newProbDecimal = Convert.ToDouble(newPropInt);

                //Call for the Finding Injector method
                BnClass.bnSetFinding(cell.Shape.ID, cell.Name, newProbDecimal);


                Visio.Shapes shapesCollections = Globals.ThisAddIn.Application.ActivePage.Shapes;
                foreach (Visio.Shape shape in shapesCollections)
                {
                    if (shape.LineStyle == "Normal")
                    {
                        Warp.VisioProbabilityUpdater(BnClass, shape.ID);
                    }
                }
               ///REMOVE UNTIL HERE
            }
        }

       This is a screenshot of my codes (which i think the colors made it easier to read than the one in here): http://screenpresso.com/=dC2ve