Best method to find controls under a dropped usercontrol - silverlight

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

Related

How can I find all controls within a control(WPF, C#)?

I found interesting questions about this like in How can I find WPF controls by name or type?, but I just want my method to return all controls within it. It doesn´t matter the control´s name or its type as long as the method returns all possible controls he can find.
In WinForms this is very easy ... just grab the WinForms container and then prob the '.Controls' property and iterate over the collection of controls returned.
foreach (System.Windows.Forms.Control ctrl in form.Controls)
{
if (ctrl.Name == "tabPageControl")
{ // do something with 'tabPageControl object' }
{
As you can see in WinForms its dead easy to get access at the global container to return a 'ControlCollection' and then iterate through or even deeper if its a panel or something like that. Once you have found what you want are simply building a list of what can be found then do something with your list or your control.
In WPF, this is done slightly differenty. I don't have extensive WPF experience but after 15 mins of playing about I came up with this:
private void button1_Click(object sender, RoutedEventArgs e)
{
// cast out Grid object.
Grid grd = (Grid) this.Content;
// do simple testing to find out what the type is.
string s = grd.ToString();
// in VS, in debug mode, hover 'grd.Children' and Smart Tool Tip that pops
// it will tell exactly under a 'count' property how many controls there are sitting
// on the global container. For me it was just 1, my Button.
foreach (UIElement child in grd.Children)
{
// do some more testing to make sure have got the right control. pref in an If statement but anyhooo.
String sss = child.GetType().FullName;
// cast out the appropriate type.
Button myWpfButton = (Button)child;
}
}
I hope thats enought to get you started.
It depends on the type of parent control. If it is an extension of ContentControl it can only have a single child element, which is found under the Content property.
If it is an extension of Panel it can have many child elements, which are found under the Children property.
There is no guarantee that any of those child elements are necessarily controls though - you will need to do some type checking to confirm whether or not they are of the type you are interested in.
This is also only for a single level of parent-child hierarchy, but should be simple enough to make recursive if you need all child controls.

Get the Grid data in ColumnHeaderClick

Sorrry guys, I'm stuck here.
I have a few grids, I also have CollectionViewSource objects associated with those grids.
Now, I'm trying to apply CollectionViewSource.SortDescriptions in ColumnHeaderClick method, and now I have to define almost the same method for each grid.
But the only thing I really need is to obtain in which Grid is happenning.
How to get that, I have no idea. Help me please.
VisualTreeHelper.GetParent didn't work.
I think, probably, the best thing would be to derive your own grid control, adding the common functionality that you want. as for finding the the column that was clicked, here is some source code....
protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnPreviewMouseLeftButtonUp(e);
if ( e.OriginalSource is GridViewColumnHeader)
{
GridViewColumn col = ((GridViewColumnHeader)e.OriginalSource).Column as GridViewColumn;
DoStuffWithYourColumn( col );
}
}
oh, and one thing, you really should use the custom sorter instead of sort descriptions--sort descriptions are REALLY slow. take a look at this article for more information on the subject.
Oh.. it's turned out that it's possible to change the SortDesriptions directly in
(((System.Windows.Controls.ListBox)(sender)).Items)

Designing Windows.Form with multiple panels -> How to hide one panel (like a PS layer)

How can I hide one panel in Visual Studio 2008 Form Designer like a layer in PS? Otherwise, can someone recommend another better method to design multiple "screens" that must be clicked through by the user?
What you describe is a wizard, and you might want to investigate the approach from Eric J.
However, when I have cases where I want to have multiple panels in the same space within my UI and I want to switch between them in the designer, I like to use a TabControl and hide the tabs on the TabControl. This makes the UI easier to manage at design time and the code is pretty simple to switch between the tabs at run time.
I made a custom control that derives from TabControl called HiddenTabsControl that is very simple. The class only overrides the WndProc and lets the TabControl base class handle everything else. All you need to do is:
Add a New Item to your project
Choose Custom Control,
Name it something like HiddenTabsControl.
Change the base Class to TabControl, remove the Constructor and the OnPaint override that Visual Studio added.
Copy this override for WndProc into the class:
protected override void WndProc(ref Message m)
{
// Hide tabs by trapping the TCM_ADJUSTRECT message
if (m.Msg == 0x1328 && !DesignMode)
{
m.Result = (IntPtr)1;
}
else
{
base.WndProc(ref m);
}
}
Now you can change tabs in the designer and design the UI easily and in the code you can handle events to change tabs as needed. Changing the Selected tab is easily done with:
this.hiddenTabsControl.SelectedTab = this.tabPageYouWantVisible;
One side effect of removing the tabs is the space that the tabs occupy when the control is constructed. Removing them will make the space the HiddenTabsControl occupies change by shrinking it. I usually set the Anchor of the HiddenTabsControl to bottom to keep it from shrinking.
I used this Wizard code in a recent project and it worked well.
It provides the basic experience you are after.
Another less elegant, but quick hack, approach is to simply not add the panel to the parent form until runtime. In doing that, the designer has no idea where the panel belongs prior to compilation, and it won't be displayed.
For example, find the block of code where you add controls to the parent form:
//this->Controls->Add(this->panel_X);
this->Controls->Add(this->tabControl);
this->Controls->Add(this->menuStrip_topMenu);
Comment or remove the statement, then find the handle to the event that occurs when the form is loaded:
this->Load += gcnew System::EventHandler(this, &MainForm::MainForm_Load);
Then in the definition of the event handler, add the control to the form:
System::Void MainForm_Load(System::Object^ sender, System::EventArgs^ e) {
...
...
this->Controls->Add(this->panel_X);
}
I haven't experienced any unwanted side effects by doing this, but if anyone has a good reason to not I'd be interested in hearing it.

Overrriding HitTestCore method for detecting multiple controls in WPF

I am creating a custom control which does hit testing on its children. I'm planning on overriding the HitTestCore method to return multiple controls which fall inside or intersects with a Geometric region. Just wondering if anyone else has tried this. Do you have any pointers for me? Or is there another way which I can do this (without actually overriding the HitTestCore method)? Thanks in advance for any help. :)
So, I was able to get multiple controls seems like I didn't need to override the HitTestCore method.
I created a HitTestFilterCallback and whenever it hit on a CheckBox (which was the type of control I was hit testing) I saved it onto a list called _hitTestResults. But I'm not sure whether this is the right way to do this :S
Here is what I did:
HitTestFilterBehavior OnHitTestFilter(DependencyObject target)
{
if (target.GetType() == typeof(CheckBox))
{
_hitTestResults.Add(target as CheckBox); // add the hittest result
return HitTestFilterBehavior.ContinueSkipChildren;
}
else
return HitTestFilterBehavior.Continue;
}

Silverlight, custom object for shapes

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".

Resources