Visio Drawing Control: Some events not responding after closing modal dialog - multithreading

I have 2 shapes in the main form. shapes have a context menu item "dummy" which is linked to a queue marker event. It opens a modal form using ShowDialog(). When I close it, some events are not responding.
Right-click doesn't work. shape selection works if you try repeatedly.
Mouse movement works.
I am doing a Dispose() on the modal form.
below is the code. I am using Visio 2019. But this happens with latest visio subscription as well. I have x64 machine. .net is 4+
Please help me with this.
using Visio = Microsoft.Office.Interop.Visio;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Dialog: Form
{
public Dialog()
{
InitializeComponent();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
axDrawingControl1.Src = "";
axDrawingControl1.Document.Application.MarkerEvent += Application_MarkerEvent;
Visio.Shape shape = axDrawingControl1.Document.Application.ActivePage.DrawRectangle(0, 0, 1, 1);
shape.AddSection((short)Visio.VisSectionIndices.visSectionAction);
shape.AddRow((short)Visio.VisSectionIndices.visSectionAction, 0, (short)Visio.VisRowTags.visTagDefault);
shape.CellsSRC[(short)Visio.VisSectionIndices.visSectionAction, 0, (short)Visio.VisCellIndices.visActionMenu].FormulaU = "\"Dummy\"";
shape.CellsSRC[(short)Visio.VisSectionIndices.visSectionAction, 0, (short)Visio.VisCellIndices.visActionAction].FormulaU = $"QUEUEMARKEREVENT(\"abc\")";
shape = axDrawingControl1.Document.Application.ActivePage.DrawOval(0, 0, 1, 1);
shape.AddSection((short)Visio.VisSectionIndices.visSectionAction);
shape.AddRow((short)Visio.VisSectionIndices.visSectionAction, 0, (short)Visio.VisRowTags.visTagDefault);
shape.CellsSRC[(short)Visio.VisSectionIndices.visSectionAction, 0, (short)Visio.VisCellIndices.visActionMenu].FormulaU = "\"Dummy\"";
shape.CellsSRC[(short)Visio.VisSectionIndices.visSectionAction, 0, (short)Visio.VisCellIndices.visActionAction].FormulaU = $"QUEUEMARKEREVENT(\"def\")";
}
private void Application_MarkerEvent(Visio.Application app, int SequenceNum, string ContextString)
{
Dialog dlg = null;
dlg = new Dialog();
dlg.ShowDialog();
//I close form
dlg.Dispose();
}
}
}

You don't need to do the
dlg.Dispose()
at that point, in fact that is probably what is causing the problem. The dispose will happen when you do a OK or Cancel on the form. Until then you still need the dlg object.

Related

c# visual studio WPF Application Output from MainWindow textbox to Secondary window

Ok, I'm a noob so go easy on me.
I have created an app in WPF using c#.
Of the many functions I have made one is a textbox that shows a countdown from 1:0:0 to 0.
This has a start/reset, play/pause, +30sec, -30 sec buttons attached.
They all work perfectly. However, I need the output showing from that particular textbox to show in a secondary window I have created in either another or duplicated textbox.
Is this even possible?
Thanks
public void CountDownTimer()
{
_timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
{
// _time = TimeSpan.FromMinutes(60);
ShowTimer.Text = _time.ToString("c");
if (_time == TimeSpan.Zero) _timer.Stop();
_time = _time.Add(TimeSpan.FromSeconds(-1));
}, Application.Current.Dispatcher);
}
//STARTS TIMER FROM 1HOUR ALSO RESETS
private void StartButton_Click(object sender, RoutedEventArgs e)
{
_time = TimeSpan.FromMinutes(60);
_timer.Start();
}
//PAUSES AND COMMENCES TIMER NOTE: THIS DOES NOT RESET THE TIMER
private void PauseButton_Click(object sender, RoutedEventArgs e)
{
if (_timer.IsEnabled)
{
_timer.Stop();
}
else _timer.Start();
}
I know you're aware that there's bad practice here, so I won't chew you out for that. :D
The easiest way to achieve what you want is to have the secondary window as a member of the first window, then change your DispatchTimer's callback to
_timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
{
// _time = TimeSpan.FromMinutes(60);
ShowTimer.Text = _time.ToString("c");
if (_time == TimeSpan.Zero) _timer.Stop();
_time = _time.Add(TimeSpan.FromSeconds(-1));
secondaryWindow.TextBoxTimer = _time;
}, Application.Current.Dispatcher);
It depends on where and how you instantiate your secondary window, and if the first window has reference to it. You might also consider raising an event when the timer changes, and subscribing the secondary window to that event with a handler that updates the textbox. Better yet, don't use controls like TextBox as a variable, but bind them to a property in another class. That's a step towards MVVM.

Converting ToolBar to ToolStrip control and MouseHover not working

I have a large winform application which we working to modify the appearance. I am replacing System.Windows.Forms.Toolbar to System.Windows.Forms.ToolStrip control. I use a custom renderer to change dropdown arrow color. with default renderer i get mouse hover effects in toolstrip but with my custom rendering it dont seem to work. Here's my code.
Tool strip initialization:I removed unnecessary code for reading comfort
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.toolStripDropDownButton1 = new System.Windows.Forms.ToolStripDropDownButton();
this.toolStrip1.ImageList = this.imageList1;
this.toolStrip1.ImageScalingSize = new System.Drawing.Size(55, 32);
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripDropDownButton1
});
this.toolStrip1.Renderer = new MyRenderer();
Toolstrip dropdown button:
this.toolStripDropDownButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.toolStripDropDownButton1.ImageIndex = 0;
this.toolStripDropDownButton1.Name = "toolStripDropDownButton1";
CustomRenderer
public class MyRenderer : ToolStripRenderer
{
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
{
e.ArrowColor = Color.White;
base.OnRenderArrow(e);
}
}
thanks to #LarsTech for his help. I found this working. I made this below modification in renderer and in code.
Added this line in initialization
this.Toolstip1.RenderMode = ToolStripRenderMode.Professional;
CustomRenderer
public class MyRenderer : ToolStripProfessionalRenderer //Professional renderer
{
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
{
e.ArrowColor = Color.White;
base.OnRenderArrow(e);
}
}

FormSheet modal dialog won't hide

I have a modal dialog that I show using the following code:
private void ShowUpdateDialog(float version, bool breakingChanges, string hint, string storeLink, string changelog, params string[] pars)
{
var dialog = new UpdatePopupController(this, new RectangleF(20, 20, 550, 600));
dialog.WantsFullScreenLayout = true;
dialog.ModalPresentationStyle = UIModalPresentationStyle.FormSheet;
dialog.ModalTransitionStyle = UIModalTransitionStyle.FlipHorizontal;
dialog.ModalInPopover = true;
UIDevice.CurrentDevice.BeginGeneratingDeviceOrientationNotifications();
dialog.ShowData(version, breakingChanges, hint, storeLink, changelog, pars);
dialog.WillRotate(UIApplication.SharedApplication.StatusBarOrientation, 0);
NavigationController.PresentModalViewController(dialog, true);
dialog.BecomeFirstResponder();
}
I get this result (that is what I expected):
Now I want to implement closing the dialog by taping out of the gray content of the dialog. How can I do it? The dialog itself inherits from UIViewController.
Dont make it Modal. Then it works
dialog.ModalInPopover = false;
See this question which asks the same thing.
Personally I would have a button which upon TouchDown would dismiss the modal view.

Outlook add in , text box , delete\backspace not working

I developed an outlook add in (custom task pane), with web browser in the user control.
All the things working well beside the backspace or the delete button when I am writing something in text box in the web browser, I can't use those keys, am I missing something?
I am a few years late to the party but I managed to fix this. The easiest way to fix this is to ensure proper focus is given to the input fields, so you will need to be able to run your own javascript on whatever page is being loaded.
The javascript I run on the page is as follows (using jQuery):
$(document).on("click", function (e) {
// first let the add-in give focus to our CustomTaskPane
window.external.focus();
// then in our web browser give focus to whatever element was clicked on
$(e.target).focus();
});
the window.external variable contains code run from the plugin (c# or VB I assume) which is exposed so we can interact from web page back to the add-in.
In the add-in code for the custom taskpane set the context of window.external:
// event when webBrowser is finished loading document
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// sets context of window.external to functions defined on this context
webBrowser1.ObjectForScripting = this;
}
And a public method for focusing:
// can be called by the web browser as window.external.focus()
public void focus()
{
this.Focus();
}
This worked for me, and I hope it helps others. Although do note that this probably doesn't work if the user keyboard navigates using tab, but you can either extend this code for that use case, or safely assume that the average outlook user will have his hand glued to the mouse.
Ok I solved the problem ,
The problem is that the custom task pane in not always gets fucos from the outlook.
So, I raised an event every time that there is "onclick" for all the pane, and then forced the pane to be in focus.
spent a lot of time trying to get this working in Outlook v16.0.13801.20288 the above did not work for me. I ended up with this working code.
Create a user control and add your webbrowser control to it then customize the .cs as below
private void CreateTaskPane() {
MyWinFormUserControl webBrowser = new MyWinFormUserControl();
webBrowser.webBrowser3.Url = new Uri("https://google.com");
webBrowser.webBrowser3.Width = 500;
webBrowser.webBrowser3.Dock = DockStyle.Fill;
webBrowser.webBrowser3.Visible = true;
webBrowser.Width = 500;
webBrowser.Dock = DockStyle.Fill;
webBrowser.Visible = true;
this.CRMTaskPaneControl = CustomTaskPanes.Add(webBrowser, "My App");
//Components.WebViewContainerWPFUserControl webView = (Components.WebViewContainerWPFUserControl)_eh.Child;
//webView.webview.Source = new Uri("https://localhost:3000");
this.CRMTaskPaneControl.Width = 500;
System.Windows.Forms.Application.DoEvents();
this.CRMTaskPaneControl.Control.Focus();
this.CRMTaskPane.Visible = true;
}
public partial class MyWinFormUserControl : UserControl
{
public WebBrowser webBrowser3;
public System.Windows.Forms.WebBrowser webBrowser1;
public MyWinFormUserControl()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.webBrowser3 = new System.Windows.Forms.WebBrowser();
this.SuspendLayout();
//
// webBrowser3
//
this.webBrowser3.Dock = System.Windows.Forms.DockStyle.Fill;
this.webBrowser3.Location = new System.Drawing.Point(0, 0);
this.webBrowser3.MinimumSize = new System.Drawing.Size(20, 20);
this.webBrowser3.Name = "webBrowser3";
this.webBrowser3.Size = new System.Drawing.Size(500, 749);
this.webBrowser3.TabIndex = 0;
this.webBrowser3.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.webBrowser3_DocumentCompleted);
//
// MyWinFormUserControl
//
this.Controls.Add(this.webBrowser3);
this.Name = "MyWinFormUserControl";
this.Size = new System.Drawing.Size(500, 749);
this.Load += new System.EventHandler(this.MyWinFormUserControl_Load);
this.ResumeLayout(false);
}
void webBrowser3_DocumentCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{
HtmlDocument doc;
doc = webBrowser3.Document;
doc.Click += doc_Click;
}
void doc_Click(object sender, HtmlElementEventArgs e)
{
this.Focus(); // force user control to have the focus
HtmlElement elem = webBrowser3.Document.GetElementFromPoint(e.ClientMousePosition);
elem.Focus(); // then let the clicked control to have focus
}
private void MyWinFormUserControl_Load(object sender, EventArgs e)
{
//Control loaded
}
Turns out this is an easy issue to fix.
Just write
class MyBrowser : WebBrowser {}
Then use MyBrowser instead of the .NET one.

How can I animate a View to fly in from the bottom of the screen?

I'm trying to figure out how to have a view. Let's call it ThirdView. It should slide up from the bottom of the screen when a user clicks a particular button on SecondView.
You'll want to create the ThirdView in your SecondView and present it as a modal view, passing in the secondView in the constructor. This will be the easiest way of animating it in the way you would like.
var thirdView = new ThirdView(secondView);
this.PresentModalViewController(thirdView, true);
In your third view, you'll want to call the passed-in SecondView and call:
secondView.DismissModalViewControllerAnimated(true);
Here is a complete working example. It is a tad simpler than in chrisntr's answer...though the above example is what I used to figure everything out.
The coolest thing about this method is that for an artistic custom UI (like the one I am building for a game), there is no off-the-shelf UI elements like the TabBar, Navigation bars, etc. The most creative applications don't use standard UI stuff.
In your main.cs file, in your finishedlaunching block:
ViewController myUIV = new ViewController();
window.AddSubview(myUIV.View);
window.MakeKeyAndVisble();
And then in a new code file add this code:
using System;
using System.Drawing;
using MonoTouch.UIKit;
namespace AnimationTest
{
public class ViewController : UIViewController
{
UIButton uib = new UIButton(new RectangleF(100, 100, 40, 40));
public override void ViewDidLoad()
{
Console.WriteLine("UI1");
this.View.BackgroundColor = UIColor.Blue;
uib.BackgroundColor = UIColor.White;
uib.TouchUpInside += delegate {
Console.WriteLine("Hey!");
var vc2 = new SecondController();
PresentModalViewController(vc2, true);
};
this.View.AddSubview(uib);
base.ViewDidLoad();
}
}
public class SecondController : UIViewController
{
UIButton uib = new UIButton(new RectangleF(100, 100, 40, 40));
public override void ViewDidLoad()
{
this.View.BackgroundColor = UIColor.White;
uib.BackgroundColor = UIColor.Red;
uib.TouchUpInside += delegate {
this.DismissModalViewControllerAnimated(true);
};
this.View.AddSubview(uib);
base.ViewDidLoad();
}
}

Resources