Interop WPF in WinForms, how to handle events from WPF control - c#

I'm working with some WPF Interoperability in a WinForms application. I have the following set up.
WinForms UserControl WFControl
WPF UserControl GalleryControl
ListBox GalleryItems
ListBox ItemTemplate GalleryItem
Winforms hosting the GalleryControl, which has GalleryItems (ListBox) that has a ItemTemplate of GalleryItem.
Now in the WFControl I want to see when GalleryItems has it's SelectionChanged Event triggered.
My current attempts have tried to:
Handle the SelectionChanged Event in GalleryControl and have it raise a seperate public event that my winforms can read, but I can't handle the event like that since it's not a routed event. This would work if I could figure out how to handle that. applicable code:
public event ClaimGallery SelectedClaimChanged;
public ViewModels.InsuranceClaimViewModel ClaimViewModel { get; set; }
public int SelectedClaimID
{
get
{
return ((Models.InsuranceClaim) ClaimList.SelectedItem).ID;
}
}
public ClaimGallery()
{
InitializeComponent();
ClaimViewModel = new ViewModels.InsuranceClaimViewModel();
DataContext = ClaimViewModel;
ClaimList.ItemsSource = ClaimViewModel.InsuranceClaims;
ClaimList.SelectionChanged += ClaimSelectionChanged;
}
private void ClaimSelectionChanged(object sender, EventArgs e)
{
//This is the part that doesn't work
ClaimList.RaiseEvent(new RoutedEventArgs(SelectedClaimChanged, this));
}
I've also seen that I could potentially find the ListBox via some control tree browsing the subscribe to the actual event in the WFControl but I can't seem to figure how to do this in an interop'd control.

I have similar problems in my current project, and I'm solving it the way you describe.
The WPF controls re-raises a public (normal) event, that is then handled by the WinForms control.
Honestly I don't get the part where you are stating that is has to be routed in order to be handled by Winforms.
my winforms can read, but I can't handle the event like that since it's not a routed event
you use "+=" to handle this one ...

Related

How manage raising events of UserControls with TestStack.White?

I'm testing my wpf application and I need to verify if certain usercontrol events correctly raise or not like, for example, Loaded/Unloaded events.
I've already created my UserControl class (I'm using DevExpress WPF Controls) because I know that TestStack.White doesn't support natively third party controls, the code is this:
[ControlTypeMapping(CustomUIItemType.Custom, WindowsFramework.Wpf)]
public class UserControl : CustomUIItem
{
public UserControl(
AutomationElement automationElement,
ActionListener actionListener)
: base(automationElement, actionListener)
{
}
protected UserControl()
{
}
public event RoutedEventHandler Loaded;
public event RoutedEventHandler Unloaded;
}
but now I don't understand how I can verify events raising or not. Does anyone help me? Thanks

C# click on control

I'm trying to create a custom control which fires an even on click.
My control is just a panel with a couple of labels and a picturebox inside.
The click works perfectly, the only issue is that I have to click the background of the control and if I press on the picturebox, is not working.
I've added the on click event to the control, but I would like to press in every place of it to trigger the event, not just the background of the panel.
I thought about adding a transparent object that covers entirely the control. I actually don't like this idea, however, I've tried with a picturebox, but i cannot see through it. It's not transparent. I can just see the panel background but It covers the labels and the image.
Thanks for the support.
If you just have a couple of objects in your panel, you can hook the Click event of all objects it contains to the same event handler, there is nothing wrong doing this.
public class MyUserControl : UserControl
{
public event Action<MyUserControl> MyControlClick
public string ID {get; set;}
public MyUserControl()
{
InitializeComponents();
// The same event handler code will be used for the three controls
myPictureBox.Click += global_Click;
myLabel1.Click += global_Click;
myLabel2.Click += global_Click;
this.Click += global_Click;
}
void global_Click(object sender, EventArgs e)
{
if (MyControlClick != null)
MyControlClick(this);
}
}
If you have a more important amount of objects, you can rely on this answer to create a truly transparent panel that handles clicks. The drawback is that you will have to detect which object has been clicked by using HitTest based on the mouse location.
On the form side :
aControl.MyControlClick += aControl_MyControlClick;
// ...
// This code is triggered when a MyUserControl is clicked
void aControl_MyControlClick(MyUserControl ctl)
{
MessageBox.Show(ctl.ID);
}
Actually! You cannot raise any event to the element in the Usercontrol unless you have to apply own method to your usercontrol or you can disable the element in the usercontrol but it will change the color of that element but It will raise the click event when you click your control.

Disabling child control events

The child controls of my custom control are obstruction the mouse events in my custom control. I have worked through the accepted answer and the answer at the bottom of this thread...
exposing-events-of-underlying-control
I haven't gotten them to work (the answer at the bottom seemed most straight forward to me). But really I would like to disable the events of them altogether. I have a pictureBox and a label, I don't need to interact with either of the child controls. Is there a way to disable them so they wont interfere with the events of my custom control?
Edit:
I'm using the custom control to gather and process a number of things and make them available as properties. When I click on it, I need to access to the properties. When the event happens at the child control, I don't have access to the propertied of my custom control. The following code is in my form...
public void Form1_MouseDown(object sender, MouseEventArgs e)
{
var myControl = sender as SubstanceViewer;
richTextBox1.Text = myControl.substanceInfo;
}
so I will need to access the properties of the parent control.
If you need the the events that are normally trapped by the child controls to be handled by the custom control itself, then simply wire up those events at run-time in the constructor of the custom control.
For example if you needed the MouseMove() event of the PictureBox and Label to fire the already wired up event of the UserControl:
public partial class SomeUserControl : UserControl
{
public SomeUserControl()
{
InitializeComponent();
this.pictureBox1.MouseMove += SomeUserControl_MouseMove;
this.label1.MouseMove += SomeUserControl_MouseMove;
}
private void SomeUserControl_MouseMove(object sender, MouseEventArgs e)
{
}
}
Be aware, though, that since different controls are firing the same handler you'll need to take that into account. For example, the e.X and e.Y values in the handler above would be relative to the source control.
*You can also wire these events up at design-time using the IDE itself, but I thought code better illustrated the solution.

Silverlight tabchanged event - tabcontrol

I'm using tab control and I want to handle tabchanged event.
I was trying to use SelectionChanged event with no luck. It's being fired too many times (after loading tabcontrol, or adding new tab).
I would like to handle this event only when user navigates between tabs.
I have found solution for WPF (Is there Selected Tab Changed Event in the standard WPF Tab Control) but it's no good for Silverlight.
TIA.
Firing "too many times" should not be a problem if you check for an actual change to the SelectedIndex property in the event.
private int LastSelectedTab = -1;
void tab_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
TabControl tab = sender as TabControl;
if (this.LastSelectedTab != tab.SelectedIndex)
{
this.LastSelectedTab = tab.SelectedIndex;
// Now do your thing...
}
}

WPF execute a function before a particular event occurs?

Is there a way to execute a piece of code before an event occurs?
example when we say Expanded="OnExpand"
here the code inside OnExpand occurs after the Expanded event occurs. What if I want to execute a piece of code before that?
You can use the Preview Events
A possible work around for the expander not having a PreviewExpanded event is to handle the PreviewMouseDown event and do a hit test to see if its on the Toggle Button.
Alternatively it may be possible to extend the Expander Class something along the lines of
I did not test this at all no idea is it really works
public class MyExpander: Expander
{
public event EventHandler<EventArgs> PreviewExpanded;
public void OnPreviewExpanded()
{
PreviewExpanded(this,new EventArgs());
}
public override void OnExpanded()
{
PreviewExpanded()
base.OnExpanded();
}
}
If you're talking about the Expander control, you could subclass it and override the IsExpanded property, raising your own PreviewExpanded event before calling base.IsExpanded = value;
If whatever object you are working with supports this behavior it will be in a matching "Preview" event. So, these two events are a before and after matched set.
KeyDown()
PreviewKeyDown()
Expander does not have a preview event for Expanded, if that is what you are working with.

Categories

Resources