Wednesday, July 18, 2012

Index - Important WPF concepts & features

Recently, I came across a scenario where I had to explain the WPF features to one person. I didn't get a common place where I can see a list of all WPF features. Now I would really like to call this as WPF cheat sheet where I can brush up my WPF skills.
The sad thing I could forecast is, as the WinRT model becomes popular and available in different platforms such as WinRT tablets, surface, windows mobile, Windows 8, future OS and other devices etc...,WPF will decline to desktop computers and rest in history. After naming the tablet as Surface, it seems Microsoft is trying to bring single platform for all devices under the Surface brand same as Google did using Android. Hope you got why I wrote this index post.

Wednesday, June 20, 2012

Drag and drop files from WPF to desktop using C#.Net

This is not only applicable to WPF but also to Windows forms applications. When I meant desktop it applies to any folder opened in windows explorer. ie the folders which we interact with for drag and drop. The scenario here is simple. We have a remote file system accessible via WCF services and showing the files and folders in the front end WPF app. It has options to upload ,download,check-out, check in etc…As part of improving usability we decided to give drag and drop facility to the screens.

Some facts about .Net drag and drop
Here are the facts about .Net file drag and drop. We cannot manipulate the file contents during the drag operation. It works only with physical files. ie we should give the drag and drop system a physical file name to start drag and drop into windows explorer or desktop. May be one reason is once the dragging mouse leaves the .Net application it is controlled by the native system ie the windows.


The drag and drop design
The above facts tells us that we can only imitate a file drag start just like it is started from windows explorer. So we should design accordingly and it is simple. As long as the .Net file drag and drop works only with the files, we should download the file before we call the DoDragAndDrop method. Is it good to download when the user starts dragging? No.So give an indication that the file is being downloaded to the client side repository /cache /temp location and allow dragging on the files which are downloaded fully.
The attached sample contains code which puts a in-memory file entity to temp folder when the dragging starts and routes the source of dragging to the file which is created in temp.

When should I call DoDragDrop
I had tried from so many places and succeeded when I called from PreviewLeftMouseButtonDown. This will block all the other operations on the mouse down operation context.


Code to drag and drop to explorer
If you look at the same you will get a clear idea how I achieved this .The FileEntry is just a class to hold the data and file name. Upon mouse event I wrote to a temp location and starts dragging using that file path. ie simply initiating a drag which we do among normal windows explorer windows.
private void Grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    FrameworkElement senderElement = (sender as FrameworkElement);
    if (senderElement != null)
    {
        FileEntry file = senderElement.DataContext as FileEntry;
        if (file != null)
        {
            string fullPath = Write2TempAndGetFullPath(file);
            //TODO : If you want to delete you need to use FileWatchers to catch the drop events and delete from temp.
            //But as long as it is temp the users/admins can delete it when required.
            DataObject dragObj = new DataObject();
            dragObj.SetFileDropList(new System.Collections.Specialized.StringCollection() { fullPath });
            DragDrop.DoDragDrop(senderElement, dragObj, DragDropEffects.Copy);
        }
    }
}
private string Write2TempAndGetFullPath(FileEntry file)
{
    string tempFilePath=System.IO.Path.Combine(_tempFolder,file.FileName);
    Stream fs=File.Create(tempFilePath);
    new StreamWriter(fs).WriteLine(file.FileContents);
    fs.Close();
    return tempFilePath;
}



Clearing temp
If you respect the word TEMP ,there is no need to worry about clearing the temp folder because that is temporary and users or admins are allowed or trained to clean that folder whenever they need more hard disk space . If you agree with me go ahead and concentrate on your application and leave the temp to users. Else ie if you are particular about cleaning temp follow the below link which employees a file watcher to clean the temp immediately after the file is dropped.

http://www.codeproject.com/Articles/23207/Drag-and-Drop-to-Windows-Folder-C

Sample
Download the sample from this link

Friday, February 24, 2012

MVVm - Embed C# code in XAML like ASP.Net MVC

It is long time since I posted something in this blog. I know this is my most famous blog with average 200hits/day but I was mainly concentrating into the other aspects of .Net such as CLR, WCF, ASP.Net, Windows Phone 7 etc than this XAML based display technology. There are 2 main inspirations for this post.

First one is a comment which I got on my post related to opacitymask and its usage in WPF. The specialty of that is, it came from a MSFT guy. I don't know how others are thinking, but for me its little important. Even I am not sure whether that MSFT is just something else or that person just added MSFT :-)

The second reason is "This is my 100th post on WPF technology and I want that to be something special and useful". I was in search for such a topic and just found today, while I was working with ASP.Net MVC 3 application.

The problem
Anyway I am not wasting time on introduction.Lets come to the topic. As everybody knows MVVm is the widely accepted pattern for the XAML based technologies such as WPF and Silverlight. The main reason I could see is the data binding support. By design the pattern is not expecting anything in the code behind and everything related to business should reside in the viewmodel. Its all fine.We can have data binding and commands to separate the view from vm. But what can I do with the dialogs? Since they are UI is that desirable to call showdialog from viewmodel or should I write code behind for views and pass the dialog result to vm through event aggregator or any other messaging mechanism? Mainly this comes into picture when we need to browse for a file or show a messagebox in MVVm based application.

There are something called behaviors and triggers in an expression blend dll named System.windows.interactivity which we can leverage to accomplish the same. But are there any better way? Yes another way is to call the ShowDialog from the vm itself and process it. This is what I was following till I came to play more with ASP.Net MVC pattern.

What is special with ASP.Net MVC
MVC is another UI pattern to separate the UI from its business. When Microsoft implemented a framework to write asp.net applications using the same, people started calling it as ASP.Net MVC. Actually there is no relation between ASP.Net and MVC .Anybody can implement MVC in their application without MSFT framework.

The specialty I noticed in MVC framework is, there is no option to write code behind. In the RAZOR view we cannot even find a code behind file. I wondered how people are accomplishing their tasks without writing the code behind for views. Theoretically we can say "don't write code behind" .But I have never seen a big enterprise application in MVVm without code behind for at least one view.Coming back to ASP.Net MVC, the RAZOR don't give us option to write code behind but provides support to embed code inside the view itself.
Yes the idea flashed in my head and I could recollect one of my old post which explains embedding code    inside the xaml file .That is the way to handle the dialog boxes better.

Solution : Embed C# or VB.Net code in xaml view
This doesn't mean we should move the code behind file into the view. This helps to write the dialog handling code in the view itself. Below is one example of such an implementation.


    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <TextBox x:Name="txtFileName"
                 Text="{Binding FilePath,UpdateSourceTrigger=PropertyChanged}" />
        <Button Grid.Column="1" Content="Browse" Click="Clicked" />
        <x:Code>
            <![CDATA[
void Clicked(object sender, RoutedEventArgs e)
{
            Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
            ofd.DefaultExt = ".exe";
            ofd.Filter = "Executables (.exe)|*.exe"; // Filter files by extension

            // Show open file dialog box
            Nullable<bool> result = ofd.ShowDialog();
            // Process open file dialog box results
            if (result.HasValue && result.Value)
            {
                // Set value to textbox which will update the property of VM
                txtFileName.Text= ofd.FileName;
            }
}
]]>
        </x:Code>
        <Button Content="Start"
                Grid.Column="2"
                Command="{Binding StartCommand}" />
    </Grid>

Pros and Cons
One thing to notice is that we need to give name to the controls which other developers may use to write code behind.Next thing how to show a message dialog box in this way .For that we need to keep a property in the vm and bind to a hidden textbox . Wire the TextChanged event of textbox to an event handler in the view as how the above C# code is written .
Main development challenge will be how to write code without intellisense .Yes you don't get intellisense when writing code inside xaml file.One way to overcome is to write the code in normal file and copy paste.