Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Thursday, July 31, 2014

MVVm views without C# code behind file

The MVVm is a great technique for separating the concerns. If we take ASP.Net MVC we can see it is built for using model view controller model. So by default wont allow us to write code behind for the views (We can write inside the cshtml though). But WPF as the technology was not built to use WPF to there is no in-built way to avoid the code behind of views. 

If the development team is so technology focused, it doesn't matter as they won't break the rules of MVVm even if there is code behind file. But since companies are offshoring to get cheap labor, enforcing quality is little tricky. As always cheap things comes with less quality. Most of the time people's priority is to get things done in quick way ie by writing everything in code behind instead of going through viewmodel. 

The challenge here is how to bring quality with these less skilled labor? One of the way to enforce viewmodel  usage is to delete the code behind of views which is nothing but the user controls.

If we just remove the usercontrol.xaml.cs, it will fail as the Initialize method is missing. So how to overcome is?

Add the Initialize method in the view itself. Yes we can write C# code in XAML. So the view user control will look as follows.

<UserControl x:Class="Joymons.MVVmDemo.Views.MainView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <x:Code>
        <![CDATA[ public MainView() { InitializeComponent(); }]]>
    </x:Code>
            <TabControl ItemsSource="{Binding ChildVMs}" SelectedIndex="0">
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Header}" />
                    </DataTemplate>
                </TabControl.ItemTemplate>
            </TabControl>
</UserControl>

I too started using VS 2013. That is why a black background in the code :)

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

Sunday, December 14, 2008

Xml to Object model using linq

Have you thought of loading xml into an object model by single line of code?
It is possible with the help of linq.Just you need to write a single statement to obtain xml 2 class object model conversion.
This post needs some basic understanding about Linq.You may get it by visiting this post.

Here is the Xml you are going to convert.
<?xml version="1.0" encoding="utf-8" ?>
<
Employees>
<
Employee ID="10">
<
Name>Joy</Name>
<
Designation>Sr Software Engg</Designation>
</
Employee>
<
Employee ID="12">
<
Name>ABC</Name>
<
Designation>Software Engg</Designation>
</
Employee>
<
Employee ID="1">
<
Name>George</Name>
<
Designation>Sr Software Engg</Designation>
</
Employee>
<
Employee ID="2">
<
Name>IJK</Name>
<
Designation>Testing Engg</Designation>
</
Employee>
<
Employee ID="3">
<
Name>XYZ</Name>
<
Designation>Team Leader</Designation>
</
Employee>
</
Employees>
The Employee class is given below
public class Employee
{
public string Name { get; set; }
public string Designation { get; set; }
}
The first step here is to load the xml into a XmlDocument.Then apply Linq.
Here goes the Linq Query.
XmlDocument xmldocument = new XmlDocument();
xmldocument.Load("../../employees.xml");
List<Employee> emps = (from i 
                       in xmldocument.ChildNodes[1].ChildNodes.Cast<XmlNode>()
                       select new Employee 
                       { 
                           Name = i.ChildNodes[0].InnerText ,
                           Designation = i.ChildNodes[1].InnerText 
                       }
                       ).ToList();

Download sample from here

Saturday, December 13, 2008

Creating custom wpf markup extension to show class fields

Here is one link which describes what is markup extension and available markup extensions.
Markup extensions are very much useful to obtain a clean project.Things won't get mixed with each other.Xaml itself contains the lines which have the functionality.

Consider the scenario where we need to display all properties of given class in a listbox.We normally write C# or VB code to get PropertyInfo objects and return the same.This code normally resides in presentation files itself.

Here comes the need for markup extension.We can write our own extension by inheriting from the MarkUpExtension class.

Steps to Create a custom markup extension

  1. Create a class which derives from MarkupExtension.The naming convention is that the class name should ends with 'Extension' .Eg:TypeDescriptorExtension
  2. If we need to accept a default parameter with extension write a constructor
  3. Add other properties as well.
  4. Override ProvideValue Method and return the appropriate value after processing.

Eg: Creating custom markup extension to list Properties and methods of a Class

The PropertyDescriptorExtension class is derived from Markupextension and it accepts an object Type as default parameter.So the constructor is written with a parameter of type 'Type'.

public class TypeDescriptorExtension:MarkupExtension
{
public TypeDescriptorExtension( Type type):this()
{
Type = type;
}
}

The other properties are IncludeProperties and InCludeMethods which are boolean to indicate whether the out put list should include Properties and Methods respectively.IncludeProperties is true by default.

Now override the ProvideValue method.Get the properties and methods collection based on the properties using Reflection and return as well.

public override object ProvideValue(IServiceProvider serviceProvider)
{
if (Type == null)
{
throw new InvalidOperationException("The Class must be specified.");
}
List<string> items = new List<string>();

if (IncludeProperties)
{
foreach (PropertyInfo item in Type.GetProperties())
{
items.Add(item.ToString());
}
}
if (IncludeMethods)
{
foreach (MethodInfo info in Type.GetMethods())
{
items.Add(info.ToString());
}
}
return items;
}

Using the TypeDescriptorExtension
Normal, which displays only properties

 <ListBox ItemsSource="{Binding Source={local:TypeDescriptor {x:Type Button}}}" />
Displays methods only
 <ListBox ItemsSource="{Binding Source={local:TypeDescriptor {x:Type Button},IncludeMethods=True,IncludeProperties=False}}" />

Sample is available here.

Wednesday, October 17, 2007

An extented VisualTreeHelper class

Usually if we want to get immediate parent of a Visual(Which considers the elements in Template also) we could use the VisualTreeHelper.GetParent method.This works easy for parent.
But think of getting the children of Visual..Its difficult to call VisualTreeHelper.GetChildren because this needs the index of child.
Here comes the role of this class which wraps these methods and makes its usage simple.

Code

public static class VisualTreeHelperEx
{
public static T FindVisualAncestorByType<T>(DependencyObject dependencyObject) where T : DependencyObject
{
if (dependencyObject == null) return default(T);
if (dependencyObject is T) return (T)dependencyObject;
T parent = default(T);
parent = FindVisualAncestorByType<T>(VisualTreeHelper.GetParent(dependencyObject));
return parent;
}
public static T FindVisualChildByType<T>(DependencyObject dependencyObject) where T : DependencyObject
{
if (dependencyObject == null) return default(T);
if (dependencyObject is T) return (T)dependencyObject;
T child = default(T);
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
child = FindVisualChildByType<T>(VisualTreeHelper.GetChild(dependencyObject, i));
if (child != null) return child;
}
return null;
}
}

Usage


Window W = VisualTreeHelperEx.FindVisualAncestorByType <Window>(grd);
Rectangle r= VisualTreeHelperEx.FindVisualChildByType<Rectangle>(grd)

Monday, May 14, 2007

Writing C# inside XAML

<Grid >

<Button Name="button1" Click="Clicked" Content="Click Me!"/>
<x:Code>
<![CDATA[
void Clicked(object sender, RoutedEventArgs e)
{
button1.Content = "Hello World";
}
]]>
</x:Code>

</Grid>