I would like to enable drag-and-drop feature for my winforms application. The main UI form is an MDI container.
I added the following code to the main form
mainuiform.AllowDrop = true;
mainuiform.DragDrop += OnDragDrop;
mainuiform.DragEnter += OnDragEnter;
The drag-and-drop does not work in the body of the application and works only on the header of the application.
Then I read that the drag-and-drop should be enabled for each child component then only we can drop a document anywhere on the application ui. This is painful as the various forms in the MDI are created by different teams.
How do I achieve this?
Add event handler to the main form (constructor)
Add event handler to all child component of the main form (in load event)
Add event handler to mdi child and its all children component (MdiChildActivate event)
since I am using DevExpress there are some DevExpress methods (there should be equivalent with winforms).
public MainMdiForm() {
RegisterDragDropEvents(this);
MdiChildActivate += OnMdiChildActivate;
}
// load event handler
private void MainMdiFormLoad(object sender, EventArgs e)
if(sender is XtraForm form)
form.ForEachChildControl(RegisterDragDropEvents);
}
private void RegisterDragDropEvents(Control control)
{
control.AllowDrop = true;
control.DragDrop += OnDragDrop;
control.DragEnter += OnDragEnter;
}
private void DeRegisterDragDropEvents(Control control)
{
control.DragDrop -= OnDragDrop;
control.DragEnter -= OnDragEnter;
}
private void OnMdiChildActivate(object sender, EventArgs e)
{
if (sender is XtraForm form)
{
// since the same event is called on activate and de active, have observed that ActiveControl == null on de active
// using the same to de register
if (form.ActiveControl == null)
{
form.ForEachChildControl(DeRegisterDragDropEvents);
}
else
{
form.ForEachChildControl(RegisterDragDropEvents);
}
}
}
void OnDragDrop(object sender, DragEventArgs e)
{
// take action here
}
void OnDragEnter(object sender, DragEventArgs e)
{
// additional check and enable only when the file is of the expected type
e.Effect = DragDropEffects.All;
}
Drag drop works on the application with this code.
Related
We use the CefSharp's ChromiumWebBrowser control (83.4.20) in Windows Forms application.
We hook up the IsBrowserInitializedChanged event to know when the browser control was initialized so we can start loading our web application. Occasionally this event is not fired at all so our application will be stuck and won't load the web app.
In case the app is stuck in initializing the ChromiumWebBrowser control, the WebView_IsBrowserInitializedChanged or WebView_LoadError are not fired:
public MainForm()
{
InitializeComponent();
this.webView.IsBrowserInitializedChanged += WebView_IsBrowserInitializedChanged;
this.webView.LoadError += WebView_LoadError;
}
private void InitializeComponent()
{
this.webView = new CefSharp.WinForms.ChromiumWebBrowser();
// usual WinForms initialization code from the designer
// ...
}
private void WebView_IsBrowserInitializedChanged(object sender, EventArgs e)
{
if (this.webView.IsBrowserInitialized)
{
this.webView.Load(this.ApplicationUri.AbsoluteUri);
}
}
private void WebView_LoadError(object sender, LoadErrorEventArgs e)
{
// handle the error
// ...
}
Are there any other events we can subscribe to to monitor the state of CefSharp and the browser control which would aid as in troubleshooting this situation?
I have a TextChanged event attached to a TextBox in a Windows Form. How to make sure if a particular call to that event wasn't triggered programmatically rather by user interacting with the TextBox?
I would like to extend #rw_'s solution a little. Inside your TextBox event handler,
private void txt_TextChanged(object sender, EventArgs e)
{
if (!(sender is null) &&((TextBox)sender).ContainsFocus)
{
//Code if triggered by Click event
}
else
{
//Code if triggered programmatically
}
}
This will help your program adjust to the case where sender object is not null for some reason.
I am unsure about what your question means. I'll split my answer.
If you want to call the text changed function programmatically and differ when it was called by user interactivity or if it was called programmatically:
Assuming that when you call the function programmatically you pass null on sender and event args txt_TextChanged(null,null);, you could use this solution:
private void txt_TextChanged(object sender, EventArgs e)
{
if(sender == null)
{
// triggered programmatically
}
else
{
// triggered by the user. sender object is the textbox interacted by the user
}
}
If you want to change the text programmatically without triggering the event:
this.txt.TextChanged -= new System.EventHandler(this.txt_TextChanged);
txt.Text = "bar";
this.txt.TextChanged += new System.EventHandler(this.txt_TextChanged);
This is a common problem. You can set a flag on your form before updating the value and then check it in your event handler:
handleEvent = false;
TextBox1.Text = "foo";
handleEvent = true;
Then in your handler, check the flag:
private void TextBox1_TextChanged(object sender, EventArgs e)
{
if(handleEvent)
{
// do stuff
}
}
I am trying to prevent users from dragging images that display in my webbrowser control.
I tried setting webbrowser.Document.MouseOver e.Cursor = Cursors.No Still not working.
I tried a few other ways.
I am unable to prevent images being dragged on the desktop.
Is it possible to prevent dragging of images from webbrowser control to desktop?
There is a way to prevent the body element of the HTML document to handle drag operation.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
this.webBrowser1.Url = new Uri("https://www.google.bg/search?q=stackoverflow&biw=1920&bih=950&source=lnms&tbm=isch&sa=X&sqi=2&ved=0ahUKEwjw2cWH4oTQAhVG8RQKHWCWB4AQ_AUIBigB");
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
this.webBrowser1.Document.Body.Drag += new HtmlElementEventHandler(Body_Drag);
}
private void Body_Drag(object sender, HtmlElementEventArgs e)
{
e.ReturnValue = false;
}
}
I need to know if there is a way to access to the events of the buttons inside a RepositoryItemTimeSpanEdit.
Image to see the buttons I need the events for: Click
Image
I have tried to access in the PopUp event and QueryPopUp, however I can't get the button in any way yet.
You can get this form through Form.OwnedForms property in Popup event. The type of this form is DevExpress.XtraEditors.Popup.TimeSpanEditDropDownForm, so you need just to find the form of this type. After that you can access buttons by using TimeSpanEditDropDownForm.OkButton property and TimeSpanEditDropDownForm.CloseButton property.
Here is example:
private void repositoryItemTimeSpanEdit1_Popup(object sender, EventArgs e)
{
var popupForm = (TimeSpanEditDropDownForm)OwnedForms.FirstOrDefault(item => item is TimeSpanEditDropDownForm);
if (popupForm == null)
return;
popupForm.OkButton.Click += OkButton_Click;
popupForm.CloseButton.Click += CloseButton_Click;
}
private void OkButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Ok");
}
private void CloseButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Cancel");
}
I write certain code in my form ResizeEnd event. Now problem is when form is moved by clicking and dragging on the caption bar, ResizeEnd event is fired and code is executed even though form size is NOT changed.
I gone through MSDN documentation for Resizeend event and it says that event will fire when form is moved (don't understand why this happens when the size is NOT changed).
For resolution I put the if condition to check if size is changed like below to stop execution of code on form move:
int Prv_Height; int Prv_Width;
private void TemplateGrid_ResizeEnd(object sender, EventArgs e)
{
if (this.Size.Width != Prv_Width || this.Size.Height != Prv_Height)
{
Prv_Width = this.Size.Width;
Prv_Height = this.Size.Height;
//Other code here when form resize ends...
}
}
So is there any way to stop ResizeEnd event to fire when form is moved? or any other better approach to solve the problem?
You could move your check for sizechange to a new baseform. On derived forms the resizeEnd event will then only fire if the size is actually changed.
public partial class CustomForm : Form
{
private Size _prvSize;
public CustomForm()
{
InitializeComponent();
}
protected override void OnShown(EventArgs e)
{
_prvSize = this.Size;
base.OnShown(e);
}
protected override void OnResizeEnd(EventArgs e)
{
if (this.Size == _prvSize)
return;
_prvSize = this.Size;
base.OnResizeEnd(e);
}
}
private void Form1_ResizeBegin(object sender, EventArgs e)
{
oldSize = ClientSize;
}
private Size oldSize = new Size();
private void Form1_ResizeEnd(object sender, EventArgs e)
{
if (oldSize == ClientSize)
return;
//Add Something
}