I have WPF control hosted inside a WinForms control using ElementHost. The WinForms control has a context menu. I want to show the context menu when user right click on the WPF control. How can this be done? It seems mouse event is not bubbled from WPF to WinForms.
it is not automatically bubbled up, as you might have handled it in the WPF control in the first place. However, you can easily add this yourself.
In your WPF user control, expose an event that you trigger on right mouse up:
public event Action ShowContext;
private void rectangle1_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
if (ShowContext != null)
{
ShowContext();
}
}
Then in your winforms control with element host you can use it like so:
public UserControl1 WpfControl { get; set; }
public Form1()
{
InitializeComponent();
WpfControl = new UserControl1();
WpfControl.ShowContext += () => contextMenuStrip1.Show(Cursor.Position);
elementHost1.Child = WpfControl;
....
Related
Is there any way to disable tab indexing for whole app (all controls) in WPF using KeyboardNavigation.TabNavigation?
Another potentially safer approach would be to handle the PreviewKeyDown event of the window programmatically:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
PreviewKeyDown += (s, e) =>
{
e.Handled = e.Key == Key.Tab;
};
}
}
I think I found solution. Placing KeyboardNavigation.TabNavigation="None" on header section inside MainWindow.xaml solved it
Does XAML provide a way to detect if the user's mouse cursor has left the Silverlight window? If so, how would I go about doing this?
Thanks for your help.
Yes there is.
Assuming the the MainPage is your RootVisual and you've added a reference for System.Windows.Browser assembly then the following code should work.
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
//objSilverlight is the <object> tag id
var element = HtmlPage.Document.GetElementById("objSilverlight");
element.AttachEvent("onmouseout", new EventHandler(HandleMouseOut));
}
public void HandleMouseOut(object sender, EventArgs args)
{
//handle your event here
}
}
Basically the .Net event handler is being attached to the onmouseout DOM event in the Html object element that contains the silverlight plugin.
I have 2 controls on a form. One numericUpDown (from the Silverlight Toolkit) and a simple Rectangle.
On the MouseLeftButtonDown of the Rectangle I popup a MessageBox with the numericUpDown value.
If I use the arrows to change the value of the numericUpDown, everyting is fine. But if I edit the value manually (with the keyboard) and immediately click on the Rectangle it shows the previous value of the numericUpDown. If I click a sencond time on the rectangle it will show the new value.
The numericUpDown.ValueChanged event is raised after the Rectangle.MouseLeftButtonDown event.
Is that a Silverlight bug? Anybody knows a workaround for that?
(btw I cannot change my Rectangle controls or events)
As workaround I propose you to create your own control like:
public class MyNumericUpDown : NumericUpDown
{
private TextBox _textBox;
public void Sync()
{
ApplyValue(_textBox.Text);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_textBox = (TextBox)GetTemplateChild("Text");
}
}
Now you can use method Sync to syncronize display text with control Value property. You can call method from XAML declaratively or in code behind. In your case:
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
myNumericUpDown.Sync();
MessageBox.Show(myNumericUpDown.Value.ToString());
}
I have a button inside my UserControl. I have three instances of this UserControl on the same page.
How can I expose the click event of the button inside such that I can assign different events for each instance of my UserControl.
I think this is similar to concept behind exposing DependencyProperty but I don't understand how to do it for events.
Thanks.
I normally add an event of the same name (and same parameters) to the user control and subscribe to the child control's original event, so I can pass the event on:
public partial class ClickEventControl : UserControl
{
public event EventHandler<RoutedEventArgs> Click;
public ClickEventControl()
{
InitializeComponent();
}
private void aButton_Click(object sender, RoutedEventArgs e)
{
if (Click != null)
{
Click(sender, e);
}
}
}
I would also be interested if there is a more general way of doing it.
I have a UserControl in my WPF application.
I want to call a click event and do some things when the user clicked the UserControl.
The problem is- the UserControl doesn't have a click event.
I searched on the web and found that you can use the MouseLeftButtonUp event.
I tried it- but it doesn't respond to my clicks.
You didn't write what you are trying to do but if you need a click event maybe you are writing some kind of button (the Button class is actually "something you can click" with the visual representation in a control template you can replace)
If you need a button with complex content inside - put your user control inside a button
If you need a button that doesn't look like a button write a custom control template for button
If you need a button with extra functionality subclass button, add the extra data/behavior in code and put the display XAML in a style.
I think for your needs PreviewMouseLeftButtonUp(Down) event is more suitable. Then you need to handle ClickCount for counting amount of clicks and then raise your own event, on which other controls will know, that your control is clicked. There are much more methods on handling click event. You should look at this msdn article and this
UPDATE to handle both Click and DoubleClick
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
_myCustomUserControl.MouseLeftButtonUp += new MouseButtonEventHandler(_myCustomUserControl_MouseLeftButtonUp);
_myCustomUserControl.MouseDoubleClick += new MouseButtonEventHandler(_myCustomUserControl_MouseDoubleClick);
}
bool _doubleClicked;
void _myCustomUserControl_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
_textBlock.Text = "Mouse left button clicked twice";
_doubleClicked = true;
e.Handled = true;
}
void _myCustomUserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_doubleClicked)
{
_doubleClicked = false;
return;
}
_textBlock.Text = "Mouse left button clicked once";
e.Handled = true;
}
}
To test this example name your control as _myCustomUserControl and add a TextBlock named _textBlock to your MainWindow.xaml
Why not just use MouseDown?
Put the event in the User Control and simply do this:
private void MyControl_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
MessageBox.Show("Clicked!");
}
}