Drag Drop using Listboxes – Part 2

In this post I will demo on how one can create a more advanced Drag Drop for ListBoxes than the one I posted earlier here.

Basically what we will do in this post is to create an Adorner for the ListBoxItem being dragged.We will have to create our own Adorner in order to show the ListBoxItem being dragged and then add that Adorner instance to the Parent control that is holding both the “source”ListBox and the “destination” ListBox. I got most of the code for this from here.

So let us start by creating the Adorner class. What we want is to display the ListBoxItem in the Adorner layer of the parent control yet we cannot just use the ListBoxItem from the original listbox because a UI Element can only belong to a single Visual Tree. So what we will do is Clone the ListBoxItem. This is very easy since a ListBoxItem is nothing more than a Content Control, so we can copy the Content and also use it’s ContentTemplate to create a Clone.

advanceddragdrop1.jpg

As you can see this helper method is doing nothing more that create a new ContentControl and setting the Content property and the ContentTemplate property from the Element that is passed and that is our Clone of the Item Selected.

Usually when using Adorner you would go ahead and do your own drawing yet in our case we are going to create a Content control and display it so we must make sure that the Layout system knows about this control. In order to do this we have to override 2 methods the MeasureOverride and the ArrangeOverride like this

advanceddragdrop2.jpg

Where elementToShow is just a reference to the ContentControl that we have created by using the CreateClone method.

Now we need to override another 2 methods so that WPF can get the elementToShow and render it.

advanceddragdrop3.jpg

Ok so by now we already have something showing up on screen. Yet right now the elementToShow is being displayed at a relative position to the AdornedElement. We would want the elementToShow to move around while dragging just like in Windows Explorer when you drag a file. So lets create a method that we can call from outside and pass the new coordinates to the Adorner.

advanceddragdrop4.jpg

Ok, so the UpdatePosition is just a method that one can call from outside the Adorner to update the position for the element. There is another method in the above code, GetDesiredTransform. We need to override this method in order to ask WPF to render our elementToShow at the point that is specified to us by the UpdatePosition method . All we need to do is create a TranslateTransform and specify the new coordinates. Without the TranslateTransform the elementToShow would be rendered relative to the Adornered element.

Ok and that is all for our Adorner, now lets have a look on how we can use it…

As explained in Part 1 of this post we need to handle the PreviewMouseLeftButtonDown of the “source” ListBox in order to grab the item to be dragged over to the “destination”ListBox. This time we will also create an instance of the adorner class we just built and add it to the AdornerLayer of the control that is parent to both the “source” ListBox and the “destination” Listbox.

advanceddragdrop5.jpg

Now that we have added the Adorner to the AdornerLayer, we only need to ask out beloved Adorner to update the position so that the elementToShow in the Adorner would move around accordingly. We will do this by handling the DragOver event of both the “source” and the “destination” ListBoxes

advanceddragdrop6.jpg

All other code is just like the Part 1 code that I have explained. The only differnce is that now we also have to remove the Adorner from the Adorner Layer once the item is Dropped on the “destination” ListBox(or even if it is dropped on the “source” ListBox since that would be like a cancel for us).

Regards

Download Source Code Here

Drag Drop using Listboxes – Part 1

[See also Part 2]

Drag Drop in WPF is not so complex once you get used to it…. Usually people blog on how to do drag drop with a canvas, I decided to do the drag drop for 2 listboxes since I think it can be more useful to application developers… + a friend, David Silverlight asked me about it so I decided to blog on it 🙂

So for our Drag and Drop exercise we will have 2 Listboxes. A “source” listbox and a “destination” listbox, so that the user can grab an item from the source and put it inside the destination listbox… In order to grab the item from the source listbox we need to handle the PreviewMouseLeftButtonDown event so that when the user holds the mouse left button down we can grab the item. Yet as you might be wondering we need to get the actual UI Element that the user selected (and then get the Content value). For this operation I created a helper method which you can see below…

dragdrop1.jpg

This method will get a UIElement by using hit testing from the point that you specify. Yet if you set a breakpoint and look at the result of the Hit test you will find out that the value that you get from the Hit Test is one of the inner control of the ListBoxItem and not the actual ListBoxItem (for example if you have a TextBlock inside your ItemTemplate of the listbox, you would get the TextBlock). So we need to climb the WPF Visual Tree until we find the ListBoxItem. We are going to do this by trial and error. So we get the UIElement from the Hit Test and pass it to the ItemsContainerGenerator to give us the object source of the ListBoxItem that we are passing. If we do not pass the correct element (i.e if the element that we pass is not the ListBoxItem) the ItemsContainerGenerator will give us back DependencyProperty.UnsetValue, if the return is that we get the Parent from the Visual Tree and try again… Quite simple…

Now that we can get the object value from a point we can grab that value and do the drag drop operation. In order to do this we need to handle the PreviewMouseLeftButtonDown of the “source” listbox as follows

dragdrop2.jpg

So here we grab the object from the “source” ListBox that we want to put in the “destination” ListBox. Then we call the DoDragDrop and pass the source listbox, the data to send in the DragDrop operation and the DragDrop effects.

Now lets implement the Drop. We have to create an event handler for the Drop event of the “destination” ListBox like the following

dragdrop3.jpg

So in the event handler of the Drop all we are doing is to get the data that we passed over with the Drag Drop and push it in the Items collection of the “destination” Listbox. It is very important that to remove the Item from the “source” ListBox you use the ItemsSource and not the Items since that would throw an InvalidOperationException because you cannot change the Items collection while doing drag drop operation on the Listbox. Now it is also important to point out that if you remove an item from the ItemsSource but you ItemsSource is not an ObservableCollection(or any other collection that implements the INotifyCollectionChanged interface), nothing will happen i.e the item will not be removed from the source listbox. Basically by changing the ItemsSource we are relying on the DataBinding for the item to be removed…

I created a demo application for this article and also for Part 2 that I will be writing very soon… maybe even tonight 🙂 Part 2 will be more advanced… It will demo on how one can give a preview of the element while dragging to the other ListBox…

Regards

Downlaod Source here

WPF Navigation Window Control Template

After posting some LINQ posts I decided to return where I really belong, WPF…

So I was wondering on what I should experiment a bit with and I found out that there are not much resources on the Navigation Window. The Navigation window is a really cool component in WPF. Did you ever have a Page and put it as the StartupUri in the App.XAML, if yes definitely you have seen the Navigation window because by default WPF uses the Navigation Window as the parent control, for you to navigate the pages. This does not imply that you can only use the Navigation Window to navigate through the pages, you can also use the Frame control. It is important to state that the navigation work is not done by the Navigation Window, the navigation is done via the NavigationService.

In this post I am not going to talk much about how the navigation service works, I will focus on how one can create a ControlTemplate for the Navigation Window. Lets start by looking at some interesting properties of the Navigation Window. I will only mention 2 of these propertiessince we are only going to use these 2 for our ControlTemplate

Properties
– BackStack – Returns a list JournalEntryUri that represent all pages that you have a visited. Unfortunatly the JournalEntryUri is an internal class so you cannot actually cast to this type. Yet since we will use binding we will by pass this problem becuase binding works with reflection so all you need to know is the propeties that you need from this class which are the Name property (which gives you the name of the page in the BackStack) and the Source property which gives you a URI for the page.

– ForwardStack – Returns a list of JornalEntryUri that represent all pages that you have returned from by using the Back command or the NavigateJournal.

Commands (for more info on commands visit this post)
NavigationCommands.BrowseBack
This command does not take any parameters. All you have to do is execute it or in case you are using a button (or any other controls that have the Command property) set the Command property to the NavigationCommands.BrowseBack. The Can Execute of this command will return true only if you have a page in the BackStack.

NavigationCommands.BrowseForward
Basically this command is the the same as the BrowseBack command but it takes the navigation forward instead of backwards

– NavigationCommands.NavigateJournal
This command is used to navigate to a specific page. As a parameter this command takes a FrameworkElement that as DataContext has a JournalEntry. Yes quites strange but this is usually what you will have at hand when trying to execute the command (we will look at this later on)

Ok, so now that we are armed with some commands and properties that we can use let’s go ahead and start building our own template for a Navigation Window that has bread crumbs 🙂

Lets start off by creating a basic control template with a back and forward button…

navwindow1.jpg

Ok, so what we created here is basically a control template for a Navigation Window that has 2 buttons for Back and Forward. Please note that I have a ContentPresenter that has the name of PART_NavWinCP. This is very important because the Navigation Window will look for a ContentPresenter of that name in order to show the pages inside it. Another important thing that we did in the code above is to set the NavigationCommands.BrowseBack to the Command property of the back button and the same for the forward button.

Now let us create our beloved bread crumbs…

navwindow3.jpg

I choose to use an ItemsControl for the bread crumbs. The ItemsSource for the ItemsControl is the BackStack property of the Navigation Window since this list has all the JournalEntries. I then forced the ItemsContol to use a WrapPanel as an Items host. The important part is the DataTemplate that I am creating. Basically I a creating a button that as Commands executes the NavigationCommands.NavigateJournal command. I am passing this command the Button object itself since this button object has the journal entry as data context (the data context for the button is “set” by the data template).

As you can see it is relativly easy to create a Control Template for a Navigation Window…. I created a nicer Control Template for the Navigation Window that you can go ahead and download…

P.S There is a problem with this. The problem is that the BackStack will give you the pages in the opposite order that you would want them 🙂 so the bread crumbs would look like this

Page3 >> Page2 >> Page1

instead of this

Page1 >> Page2 >> Page3

I created my own WrapPanel so that it inverts the elements… All I had to do is open Reflector disassemble the code and change the order of the ArrangeOverride… You can find this in the download… Any questions please contant me – marlongrech@gmail.com

Have loads of WPF fun….

Downlaod Sources for sample

Let keyword when using LINQ

I found another cool feature in LINQ (yes another one). Basically LINQ introduces a new keyword, let.

This keyword lets you declare “variables” in your query that you can use throughout the query itself and even to project data out of the query… It would look something like this…

linq.jpg

and as expected the result would be

linqoutput.jpg

Quite cool….

Regards

More LINQ and Deferred Execution

In my previous post I talked about LINQ and Deferred Execution … I decided to continue expanding on this topic by showing how with LINQ to Objects it’s not only the query that is not executed immediately. Lets start from the basics… When you have a query such as this one

linq1.jpg

you can also write the above query in this way…
linq2.jpg

Yet you still did not execute that query… i.e the query2 that we have in the above code still has no values in it, it only holds an object that can give the values that you would want to have (It’s just a plan of execution). This might sound strange yet true… WHY? It’s because of Iterators. This is very important!!! For a better understanding of how iterators work have a look at this post.
So basically the iterator (which is an object returned by the Where method) will give you one value from a list at a time ONLY when you request it. Once you request the value, then you can go ahead and process that value and request the next value from that list. We use this a lot for example when we create a foreach statement.

When you have a LINQ query the same thing would happen as if we are in a foreach statement. When you project a value from your query you did not process the whole list you only got one value at a time!!! For a better understanding of how this works I created a small demo app where I developed my own Where Iterator that prints in a console. Here is the code for this demo app.

linq31.jpg

Basically I am creating an extension method for IEnumerable<int> and called it MyOwnWhere that in essence does the same job of the Where extension method of .Net 3.5 with the difference that this one prints to console. The interesting part of all this, is the output in the console…

linq4.jpg

As you can see when you have a where query you will be going through the list only once. The MyOwnWhere method (by using the yield keyword which is the keyword for creating iterators) is emitting an integer at a time. Lets us try to write down the flow of execution…

– The foreach statement requests a value from the query
– The query will start by asking the MyOwnWhere for a value
– MyOwnWhere will start filtering the source list
– Once an item matching the lambda function passed is found we yield that value
– The body of the foreach can process that value
– Once the value is processed the foreach will request the next value and this will go back to step 1 until the MyOwnWhere will stop yield values.

So basically everything is happening “Just in time” when you request it. To summarize all this we can even say

– You request a value
– The Iterator yields that value
– You process the value and request another one

The only instances where this does not apply is when you have things like OrderBy, Group or Joins…. When you use such methods you will need to get all values before executing the order by for example. So the Where would have to be processed fully before the order by can continue…. So if we change our code to this

linq5.jpg

than the result would be this

linq6.jpg

So here we had to process the whole list before we can order the result… No more just in time over here 🙂

I hope that this post helps a bit more you guys to understand how LINQ to Objects actually works below the covers 🙂

Happy new year to everyone 🙂

Regards

LINQ and Deferred Execution of queries

Hello WPF Disciples,

LINQ is really really cool, I am in love … Today I discovered something about LINQ that made me think i was crazy for a while … Yet then I found out what is really happening and I felt really stupid …

When you create a query with LINQ the query is not executed until it’s really needed. For example

int[] list = new int[]{ 1,2,3,4,5,6,7,8,9,10 };
int max = 5;
var query = from x in list
where x <= max
select x;

foreach (var item in query)
Console.WriteLine(item);Console.ReadKey(true);

The Result of this query is a print from 1 – 5.

The query is not executed until you reach the foreach statement. Basically LINQ will delay the execution of the query till it is really needed… This makes a lot of sense and I like the idea… BUT if you are not aware of this it can make you go crazy. For example let’s take this query and put some code that changes the state an object that is used in the query

int[] list = new int[]{ 1,2,3,4,5,6,7,8,9,10 };
int max = 5;
var query = from x in list
where x <= max
select x;
max += 2;
foreach (var item in query)
Console.WriteLine(item);

Console.ReadKey(true);

The Result of this query is a print from 1 – 7

As you can see the result for this query is different because the max variable was changed before the query was executed… This can really make you go crazy if you are not aware of what is actually happening…Have a good LINQ time…. Regards