Silverlight, custom object for shapes - silverlight

I am studding Silverlight. I have an application where I create Polygons in UserControl_Loaded method. During creation stage I add MouseLeftButtonUp event handler like this:
polygon.MouseLeftButtonUp += MouseButtonEventHandler_MouseLeftButtonUp;
All polygons have the same handler.
My goal is to use a custom object when I click on a polygon.
For instance, I have two polygons; both of them have int MyCustomInt32 property. The property is set during creation stage. For the first polygon it is set to 10, for the second one to 20. When the event fires I would like to retrieve and set MyCustomInt32 value. Of course, the value should be different, it depends on which polygon I click.
Is it possible to do in Silverlight?
Thank you.

You can cast the sender parameter to your custom class type:-
private void MouseButtonEventHandler_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var polygon = (MyCustomPolygon)sender;
int x = polygon.MyCustomInt32;
}
Edit:
In reponse to your comment, the subject of actually creating an implementation of a custom control is too wide. There are however plenty of articles out in web land to review. A couple of examples are:-
Creating a Silverlight Custom Control The Basics
Craft Custom Controls for Silverlight 2
There are plenty more found with the simple web search "Custom Control Silverlight".

Related

How do I solve the following design in the MVVM paradigm? (newb)

I'm still starting out with MVVM and read through all the MSDN Prism examples but I'd nonetheless like some guidance with the following design problem which I feel will help me latch onto the Prism concepts and reinforce what I just learnt
I have a multi-window application - each window has a filter drop down control. The value of this filter control will affect the display of other controls within that same window, eg grids, charts etc.
Certain interactions (eg double clicking a row on a grid) will spawn another window which will have its own separate filter control, which will similarly affect the display of other controls only within that window
How do I implement this behavior of the filter driving the display of other user controls it has no idea of and have it restrict its behavior to only the window hosting it? How do I keep these interactions loosely coupled?
I'm thinking I need to use the EventAggregator and for the filter control to publish an update event when the selection changes? Am I thinking about this the right way? Would each window need a separate EventAggregator?
Yes, you are thinking about this the right way. The EventAggregator is a good tool for what you're doing. You'll need to have the EventAggregator on every window you plan to raise an event from. You can inject the EA into your constructor or use the ServiceLocator. Here are 2 examples:
// Ctor injection
private IEventAggregator _eventAggregator;
public ViewModelBase(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
// Service Locator
ServiceLocator.Current.GetInstance<IEventAggregator>().GetEvent<YourEvent>().Publish();
Now, you'll need to create a CompositePresentationEvent for the EA to publish. You can minimize the number of these that get created by including a payload in the CPE. Something like this:
public class NavigationSelectedEvent : CompositePresentationEvent<NavigationEnum.Destination>{}
So now you're ready to publish the event:
_eventAggregator.GetEvent<NavigationSelectedEvent>().Publish(NavigationEnum.Destination.Home);
And then subscribe to it - using an optional filter on the payload so you're not wasting resources:
this.EventAggregator.GetEvent<NavigationSelectedEvent>().Subscribe(HandleNavigationEvent, ThreadOption.UIThread, false, i => i == NavigationEnum.Destination.Home);
You should publish the filter notification using the EventAggregator, that is the best way to do it from my experience. You should be using only one EventAggregator to serve as a hub between all the subscribing objects.
Something like:
MyNotificationChangedArgs args = new MyNotificationChangedArgs();
args.Payload = GetThePayload(someParameters);
myEventAggregator.GetEvent<NotificationFilterChangedEvent>().Publish(args);
Another thing that really helps is to dependency-inject the EventAggregator, for instance via Unity. This way all of your controls can simply access the common EventAggregator by calling on the UnityContainer.Resolve method:
var myEventAggregator = myUnityContainer.Resolve<MyEventAggregator>();
Every View has access to the Model through the ViewModel. Model your filters. Then the Views bind to ViewModel representations that use the filters. Your Views don't have to know about each other, they just have to bind to the Model.

Best method to find controls under a dropped usercontrol

I'm trying to implement a drag-drop function to a usercontrol.
I've managed to get this working properly with the use of google, however, when dropping a control I wish to find every similar type controls that might be or might not be under it.
My current way would be check every control and see if it's under the dropped control. But I wonder if there is a better way, like a find control function which can check for controls within a given range?
you could use this function:
http://msdn.microsoft.com/en-us/library/system.windows.media.visualtreehelper.findelementsinhostcoordinates%28v=vs.95%29.aspx
void xy_MouseMove(object sender, MouseEventArgs e)
{
if (m_IsDraging)
{
var res = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), elemenetWhichChildrenYouWantToCheck);
//... check res for drop elements and react
}
}
Or you can just use this function only in MouseLeftButtonUp event
Well..
First, the Logical Tree is the tree of sub-controls a control is made of.
Second, check this post

wpf dual monitor application?

I'm very new to WPF. I want to create a dual monitor/projector application. What I want to do is have the "presenters screen" on one monitor and another panel on the secondary monitor, similar to how powerpoint works. I'm struggling to wrap my mind around the panels and XAML. So what I'm after is user clicks on a button on screen1 and information gets updated on screen2.
I'm using this code:
this.Width = System.Windows.SystemParameters.VirtualScreenWidth;
this.Height = System.Windows.SystemParameters.VirtualScreenHeight;
this.Top = 0;
this.Left = 0;
to set the width and height of the screen.
Edit:
The later goal is to cause screen2 to retrieve items out of a database based on the selection on screen1
Question: tutorials, places to go, nudges on how to update monitor2 from a button on monitor1
Short Answer
Create a view model that shared between two views; make one of the views the master (makes the changes) and the other pure presentation. The views are new windows. Initially do not be concerned with the window position (we'll get to that later) just get the shared viewmodel working.
Tip: research the MVVM pattern. Google has a lot of articles on the subject.
Long Answer
After you have researched MVVM and created a few example applications (from scatch or using a framework), below are few additional features you want implement to create the "powerpoint-like" application.
Fullscreen Mode
At the very least you will want the presentation window to be full screen. To achieve this, you set the WindowStyle to None and AllowsTransparency to True.
If you want to make the second window also fullscreen you may need to do some Win32 overrides to get the window to maximize properly without covering the taskbar (post a comment if you want to know how to do this).
Detect Multiple Monitors
Get the size and position of the monitors using Win32 Interop commands. There will be plenty of articles on the Internet that will help you with this (or post another StackoverFlow question).
This would be a neatâ„¢ feature as it will position the two windows correctly (use the secondary screen as the presentation).
That is all that I can think of now, post-back if you any questions on MVVM or any of the additional points above.
1) You should have 2 Windows, the way this looks I'd make monitor2 a child window of monitor1 (after all, it is a child ;)
What i mean by that, is that StartupUri in App.xaml should point to monitor1, and in monitor1's constructor, you should create an instance of monitor2 (which would be a singleton if i were to do it).
2) To maximize a window on the second screen:
Subscribe to the Loaded event of the window (in code-behind), and set
private void Window_Loaded(object sender, RoutedEventArgs e) {
WindowState = WindowState.Maximized;
}
More info (and source): here
3) As to how to make monitor2 react when you set something in monitor1, make monitor1 and monitor2 bind to the same ViewModel, only they show different stuff.
Hope this helps!

Silverlight Usercontrol Onload Event when generated in another Usercontrol, to apply farseer physics

Didn't know how to phrase the question better but basically I have a usercontrol that I dynamically add into another usercontrol. The child usercontrol has a set of images and basically I need to know if they have fully loaded inside the parent usercontrol since I need their dimentions for a method (not just height and width).
Is there a type of event that can trigger when all the images in the child usercontrol have loaded in the parent?
To further explain my scenario, I need this since I am using farseer physics engine for silverlight and it aquires the shape of the image to use for collision detection, and since when I try to turn the images into a physics object it would not find the shape since the image is still being generated on screen and therefore throws an exception.
Update: This is what I have came up with so far
void currImg_ImageOpened(object sender, RoutedEventArgs e)
{
var ImagesLoaded = true;
for (int i = 0; i < ImageLoaded.Count-1; i++)
{
if (!ImageLoaded[i])
{
ImagesLoaded = false;
ImageLoaded[i] = true;
break;
}
}
if (ImagesLoaded)
{
addPuppetPhysics(pg.currPuppet);
}
}
Where ImageLoaded is a list of booleans, the method addPuppetPhysics applies the farseer physics to the usercontrol pg.currPuppet . Thing is the physics engine finds the first half of the images then doesn't find anymore (crashes on the same Image). If I merely load the usercontrol, then apply the physics with a button click, it works perfectly.
Can you detect when the images are finished loading in the child control? If so you may be able to create you own event -- ex: ImagesLoaded -- and handle that in the parent.

How to enable user to drag/drop WPF user controls anywhere on the page?

Now that I can make useful user controls in WPF (thanks to this stackoverflow answer) I want to be able to put numerous user controls on one page in two columns and enable the user to be able to move them around according to preference, dragging the ones they use the most to the top, etc.
Can anyone point me to code, tutorials, etc. which do this? I can imagine this has been made quite easy to do in WPF.
Here is a blog post to get you started on drag drop functionality in WPF.
Have Fun.
There's also How can I drag and drop items between data bound ItemsControls? by Bea Stollnitz.
The article talks about a reusable set of adorners that enable drag-n-drop between controls.
It's somewhat advanced, but very useful.
A series of blog posts that deal with Drag and Drop using attached properties.
I know this isn't exactly what you need but it might get you close!!!
Martin Grayson has a project on Codeplex called Blacklight... Check out the Drag dock Panel!!!
I was looking for an easy way to accomplish this as well and came across the following web page: http://dotnetslackers.com/ADO_NET/re-191632_Generic_WPF_Drag_and_Drop_Adorner.aspx It looks like there are some nice features of this implementation.
For future reference, there is a great library on codeproject that has a DragCanvas which enables you to drag any controls placed on it:
http://www.codeproject.com/KB/WPF/WPFJoshSmith.aspx
It also contains a CenteredContentControl if you want to make "attachments" between controls.
Correction:
private void Control_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
isDragging = true;
var draggableControl = sender as UserControl;
clickPosition = e.GetPosition(this.Parent as UIElement);
var transform = RenderTransform as TranslateTransform;
if (transform != null) {
clickPosition.X -= transform.X;
clickPosition.Y -= transform.Y;
}
draggableControl.CaptureMouse();
}

Resources