I have a class derived from WindowsFormsHost that listens to WinForms mouse events. It works fine for single clicks but is there any way to trigger double client events? ClickCount is read-only so I can't set it, and raising Control.MouseDoubleClickEvent doesn't propagate it. Any other idea?
private void OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
MouseButton? wpfButton = ConvertToWpf(e.Button);
if (!wpfButton.HasValue)
return;
RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, wpfButton.Value) {
RoutedEvent = Mouse.MouseDownEvent,
Source = this
//ClickCount = 2 // read-only
});
//RaiseEvent(new RoutedEventArgs() { // won't propagate
// RoutedEvent = System.Windows.Controls.Control.MouseDoubleClickEvent,
// Source = this
//});
}
Here is you would raise a MouseDoubleClickEvent programmatically in WPF:
MouseButtonEventArgs doubleClickEvent = new MouseButtonEventArgs(Mouse.PrimaryDevice, (int)DateTime.Now.Ticks, MouseButton.Left);
doubleClickEvent.RoutedEvent = Control.MouseDoubleClickEvent;
doubleClickEvent.Source = this;
RaiseEvent(doubleClickEvent);
Related
On other objects like the Forms itself MouseClick event works but when it comes to ChromiumWebBrowser the event handler simply doesn't listen any mouse clicks.
The browser is in a tab page. I tried to listen mouse clicks from there but that also didn't work.
private void ChromeBrowser_MouseClick(object sender, MouseEventArgs e)
{
Log("Click");
}
Designer.cs:
//
// chromeBrowser
//
this.chromeBrowser.ActivateBrowserOnCreation = false;
this.chromeBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
this.chromeBrowser.Location = new System.Drawing.Point(3, 3);
this.chromeBrowser.Name = "chromeBrowser";
this.chromeBrowser.Size = new System.Drawing.Size(1003, 539);
this.chromeBrowser.TabIndex = 0;
this.chromeBrowser.MouseClick += new System.Windows.Forms.MouseEventHandler(this.ChromeBrowser_MouseClick);
//
I have created a C# usercontrol.
This usercontrol is hosted in a panel like so:
UserControlQuestion1 question1 = new UserControlQuestion1();
panel1.Controls.Add(question1);
panel1.Visible = true;
I want to add an event handler in my usercontrol to handle the panels VisibleChanged Event.
I have tried this which compiles correctly:
private void InitializeComponent()
{
this.Parent.VisibleChanged += new System.EventHandler(this.Parent_VisibleChanged);
But when I run my program the this.Parent is null because it hasn't been added to the parent panel yet I guess
How can I do this?
Making use of what you have so far, you could create a "Register Event" function in your user control...
void RegisterEvent()
{
this.Parent.VisibleChanged += new System.EventHandler(this.Parent_VisibleChanged);
}
which you can call after it has been added to the parent:
UserControlQuestion1 question1 = new UserControlQuestion1();
panel1.Controls.Add(question1);
question1.RegisterEvent();
panel1.Visible = true;
Set your VisibleChanged event handler after you create the control
UserControlQuestion1 question1 = new UserControlQuestion1();
panel1.Controls.Add(question1);
question1.Parent.VisibleChanged += new System.EventHandler(question1.Parent_VisibleChanged);
panel1.Visible = true;
OR
UserControlQuestion1 question1 = new UserControlQuestion1();
panel1.Controls.Add(question1);
panel1.VisibleChanged += new System.EventHandler(question1.Parent_VisibleChanged);
panel1.Visible = true;
You can try handling the ParentChanged event or override the OnParentChanged event raiser:
Control previousParent;
protected override void OnParentChanged(object sender, EventArgs e){
if(Parent != previousParent){
if(Parent != null) Parent.VisibleChanged += Parent_VisibleChanged;
if(previousParent != null) previousParent.VisibleChanged -= Parent_VisibleChanged;
previousParent = Parent;
}
}
Note that with the code above, you don't need code to register the Parent_VisibleChanged in the InitializeComponent.
In my main view I have a Listbox for which I set (among others) the PreviewMouseLeftButtonDownEvent that I use to support drag and drop re-ordering.
var style = ListBox.ItemContainerStyle;
style.Setters.Add(new Setter(AllowDropProperty, true));
style.Setters.Add(new EventSetter(PreviewMouseLeftButtonDownEvent,
new MouseButtonEventHandler(Input_Down)));
private void Input_Down(object sender, EventArgs e)
{
if (!(sender is ListBoxItem))
return;
var draggedItem = sender as ListBoxItem;
isDragging = true;
StartDrag(draggedItem);
}
private void StartDrag(ListBoxItem draggedItem)
{
draggedItem.IsSelected = true;
DragDrop.DoDragDrop(draggedItem, draggedItem.DataContext, DragDropEffects.Move);
}
In the ListBox.ItemTemplate there is a button with an Update command:
<Button Command="{Binding Path=UpdateCommand}" Content="Button"/>
However, the command is never triggered when I set the PreviewMouseLeftButtonDownEvent. If I remove the PreviewMouseLeftButtonDownEvent setter, the command works fine. Any ideas on why this is and how I can use both?
The DragDrop.doDragDrop() operation seems to block all underlying events, meaning that the commands from the buttons that are clicked are not fired.
Since I did not find any clean way of doing this, I decided to go for a hack. In the event handler of the ListBox.ItemContainerStyle I check if the original source in the RoutedEventArgs is a Button with an ICommand attached to it. If so, I abort the DragDrop.doDragDrop() procedure:
style.Setters.Add(new EventSetter(PreviewMouseLeftButtonDownEvent,
new MouseButtonEventHandler(Input_Down)));
private void Input_Down(object sender, RoutedEventArgs e)
{
if (EventTriggeredByButtonWithCommand(e))
return;
var draggedItem = sender as FrameworkElement;
if(draggedItem !=null)
StartDrag(draggedItem);
}
bool EventTriggeredByButtonWithCommand(RoutedEventArgs e)
{
var frameWorkElement = e.OriginalSource as FrameworkElement;
if (frameWorkElement == null)
return false;
var button = frameWorkElement.TemplatedParent as Button;
if (button == null)
return false;
return button.Command != null;
}
I am trying to retrieve images from media library to a warp panel inside listbox 'lstImageFromMediaLibrary', also am trying that while the images load i show a loading screen using a usercontrol and adding it to popup.child
but i am getting this exceeption 'UnauthorizedAccessException'
when i remove all backgrougWorker related code no such unauthorized access is there....
void backroungWorker_DoWork(object sender, DoWorkEventArgs e)
{
foreach (Picture p in mediaLibrary.Pictures)
{
bitmapImage.SetSource(p.GetThumbnail());
lstBitmapImage.Add(bitmapImage);
}
this.lstImageFromMediaLibrary.ItemsSource = lstBitmapImage;
}
any help is appriciated , i hope i made myself clear....
EDIT:
ok so now m doing this
BackgroundWorker backroungWorker = new BackgroundWorker();
Popup popup = new Popup();
public PanoramaPage1()
{
InitializeComponent();
showpopup();
init();
}
private void init()
{
backroungWorker.WorkerReportsProgress = true;
backroungWorker.DoWork += new DoWorkEventHandler(backroungWorker_DoWork);
backroungWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backroungWorker_RunWorkerCompleted);
backroungWorker.ProgressChanged+=new ProgressChangedEventHandler(backroungWorker_ProgressChanged);
backroungWorker.RunWorkerAsync();
}
void backroungWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
popup.IsOpen = false;
}
);
}
void backroungWorker_DoWork(object sender, DoWorkEventArgs e)
{
backroungWorker.ReportProgress(10);
}
void backroungWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.InitializePage();
}
private void showpopup()
{
popup.Child = new SplashScreenControl();
popup.Width = 480;
popup.IsOpen = true;
}
private void InitializePage()
{
MediaLibrary mediaLibrary = new MediaLibrary();
List<BitmapImage> lstBitmapImage = new List<BitmapImage>();
foreach (Picture p in mediaLibrary.Pictures)
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(p.GetThumbnail());
lstBitmapImage.Add(bitmapImage);
}
this.lstImageFromMediaLibrary.ItemsSource = lstBitmapImage;
}
but still the progress bar just shows a dot and nothing else.....
You are accessing your User Interface in your DoWork Event. You should be communicating to your application through the Background Worker Events such as the ProgressChanged or the RunWorkerCompleted Events.
From First link:
You must be careful not to manipulate any user-interface objects in your DoWork event handler. Instead, communicate to the user interface through the BackgroundWorker events.
I have two textboxes. I need to validate them before taking any other action.
private ErrorProvider _errorProviderEmail = new ErrorProvider();
private ErrorProvider _errorProviderPass = new ErrorProvider();
public FormLogin()
{
InitializeComponent();
textBoxEmail.Validating += TextBoxEmailValidating;
textBoxPass.Validating += TextBoxPassValidating;
textBoxEmail.Validated += TextBoxEmailValidated;
textBoxPass.Validated += TextBoxPassValidated;
textBoxEmail.Text = "";
textBoxPass.Text = "";
}
void TextBoxPassValidated(object sender, EventArgs e)
{
_errorProviderPass.SetError(textBoxPass, "");
}
void TextBoxEmailValidated(object sender, EventArgs e)
{
_errorProviderEmail.SetError(textBoxEmail, "");
}
void TextBoxPassValidating(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!string.IsNullOrEmpty(textBoxPass.Text)) return;
e.Cancel = true;
_errorProviderPass.SetError(textBoxPass,"Password is required!");
}
void TextBoxEmailValidating(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!string.IsNullOrEmpty(textBoxEmail.Text)) return;
e.Cancel = true;
_errorProviderEmail.SetError(textBoxEmail, "Email address is required!");
}
The problem is that only validating event for textBoxEmail is triggered, what could be wrong here, and why the validating event for textBoxPass never fires?
The individual TextBox controls only validate when they lose their focus.
Try calling the form's ValidateChildren() function to force each control to call their validation handlers:
private void button1_Click(object sender, EventArgs e) {
if (this.ValidateChildren()) {
this.Close();
}
}
Also, you only need one ErrrorProvider component.
The Validating event is raised only when the control that receives the focus has the CausesValidation property set to true.
For example, if you have written code in TextBox1's Validating event, and you click the OK button (CausesValidation = true) then the Validating event is raised, but if you click the Cancel button (CausesValidation = false) then the Validating event is not raised.
Source on CodeProject