Tuesday, December 16, 2008

Friday, July 11, 2008

How can we Resign the satelitte assembly from command prompt.

Here is the command to resign the satelitte assembly :

sn -R "YourAssemblyName.dll" "yourpublickey.snk"

Saturday, July 5, 2008

Another way to listen to dependency property change.

Ben Constable just blogs about another elegant way to listen to dependency property change, the trick here is using DependencyPropertyDescriptor, imagine that you have a Label called myLabel, and you want to get notified when it's ContentProperty is changed, then you can do something like the following:

DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(Label.ContentProperty, typeof(Label));
if (dpd != null)
{
dpd.AddValueChanged(myLabel, delegate
{
// Add your logic here to respond to value change.
});
}

The other ways in WPF that you can use to listen to property change is to subclass an existing Control, and override the metadata of a dependency property whose property change you want to listen to, when you do so, you need to specify a PropertyChangedCallback which a delegate to your property change event handler, or instead of using PropertyChangedCallback, you can override the OnPropertyChanged method, and place your logic there, as a bonus, you can get additional information things like which property is changed by examining the value of passed-in DependencyPropertyChangedEventArgs argument's Property property.

Friday, June 13, 2008

What is difference between Timer and Dispatcher

Dispatcher things

The DispatcherTimer is reevaluated at the top of every Dispatcher loop.

Timers are not guaranteed to execute exactly when the time interval occurs, but are guaranteed to not execute before the time interval occurs. This is because DispatcherTimer operations are placed on the Dispatcher queue like other operations. When the DispatcherTimer operation executes is dependent on the other jobs in the queue and their priorities.

If a System.Timers.Timer is used in a WPF application, it is worth noting that the System.Timers.Timer runs on a different thread then the user interface (UI) thread. In order to access objects on the user interface (UI) thread, it is necessary to post the operation onto the Dispatcher of the user interface (UI) thread using Invoke or BeginInvoke. Reasons for using a DispatcherTimer opposed to a System.Timers.Timer are that the DispatcherTimer runs on the same thread as the Dispatcher and a DispatcherPriority can be set on the DispatcherTimer.

A DispatcherTimer will keep an object alive whenever the object’s methods are bound to the timer.

So, the right way to schedule things inside the WPF UI is something like this.

private DispatcherTimer _timer;
timer = new DispatcherTimer(DispatcherPriority.Background);
timer.Interval = TimeSpan.FromMinutes(5);
timer.Tick += delegate { ScheduleUpdate(); };
timer.Start();

Thursday, June 5, 2008

Coordinate Systems in .Net

Before we discuss transformations, we need to understand coordinate systems. GDI+ defines three types of coordinate spaces: world, page, and device. When we ask GDI+ to draw a line from point A (x1, y1) to point B (x2, y2), these points are in the world coordinate system.

Before GDI+ draws a graphics shape on a surface, the shape goes through a few transformation stages (conversions). The first stage converts world coordinates to page coordinates. Page coordinates may or may not be the same as world coordinates, depending on the transformation. The process of converting world coordinates to page coordinates is called world transformation.

The second stage converts page coordinates to device coordinates. Device coordinates represent how a graphics shape will be displayed on a device such as a monitor or printer. The process of converting page coordinates to device coordinates is called page transformation. Figure 10.2 shows the stages of conversion from world coordinates to device coordinates.



In GDI+, the default origin of all three coordinate systems is point (0, 0), which is at the upper left corner of the client area. When we draw a line from point A (0, 0) to point B (120, 80), the line starts 0 pixels from the upper left corner in the x-direction and 0 pixels from the upper left corner in the y-direction, and it will end 120 pixels over in the x-direction and 80 pixels down in the y-direction. The line from point A (0, 0) to point B (120, 80) is shown in Figure 10.3.


Figure 10.3. Drawing a line from point (0, 0) to point (120, 80)


Drawing this line programmatically is very simple. We must have a Graphics object associated with a surface (a form or a control). We can get a Graphics object in several ways. One way is to accept the implicit object provided by a form’s paint event handler; another is to use the CreateGraphics method. Once we have a Graphics object, we call its draw and fill methods to draw and fill graphics objects. Listing 10.1 draws a line from starting point A (0, 0) to ending point B (120, 80). You can add this code to a form’s paint event handler.

Listing 10.1 Drawing a line from point (0, 0) to point (120, 80)

Graphics g = e.Graphics;
Point A = new Point(0, 0);
Point B = new Point(120, 80);
g.DrawLine(Pens.Black, A, B);


Figure 10.3 shows the output from Listing 10.1. All three coordinate systems (world, page, and device) draw a line starting from point (0, 0) in the upper left corner of the client area to point (120, 80).

Now let’s change to the page coordinate system. We draw a line from point A (0, 0) to point B (120, 80), but this time our origin is point (50, 40) instead of the upper left corner. We shift the page coordinates from point (0, 0) to point (50, 40). The TranslateTransform method of the Graphics class does this for us. We will discuss this method in more detail in the discussion that follows. For now, let’s try the code in Listing 10.2.

Listing 10.2 Drawing a line from point (0, 0) to point (120, 80) with origin (50, 40)

Graphics g = e.Graphics;
g.TranslateTransform(50, 40);
Point A = new Point(0, 0);
Point B = new Point(120, 80);
g.DrawLine(Pens.Black, A, B);



Figure 10.4 shows the output from Listing 10.2. The page coordinate system now starts at point (50, 40), so the line starts at point (0, 0) and ends at point (120, 80). The world coordinates in this case are still (0, 0) and (120, 80), but the page and device coordinates are (50, 40) and (170, 120). The device coordinates in this case are the same as the page coordinates because the page unit is in the pixel (default) format.



Figure 10.4. Drawing a line from point (0, 0) to point (120, 80) with origin (50, 40)


What is the difference between page and device coordinates? Device coordinates determine what we actually see on the screen. They can be represented in many formats, including pixels, millimeters, and inches. If the device coordinates are in pixel format, the page coordinates and device coordinates will be the same (this is typically true for monitors, but not for printers).

The PageUnit property of the Graphics class is of type GraphicsUnit enumeration. In Listing 10.3 we set the PageUnit property to inches. Now graphics objects will be measured in inches, so we need to pass inches instead of pixels. If we draw a line from point (0, 0) to point (2, 1), the line ends 2 inches from the left side and 1 inch from the top of the client area in the page coordinate system. In this case the starting and ending points are (0, 0) and (2, 1) in both world and page coordinates, but the device coordinate system converts them to inches. Hence the starting and ending points in the device coordinate system are (0, 0) and (192, 96), assuming a resolution of 96 dots per inch.

Listing 10.3 Setting the device coordinate system to inches
g.PageUnit = GraphicsUnit.Inch;
g.DrawLine(Pens.Black, 0, 0, 2, 1);


Figure 10.5 shows the output from Listing 10.3. The default width of the pen is 1 page unit, which in this case gives us a pen 1 inch wide.



Figure 10.5. Drawing with the GraphicsUnit.Inch option


Now let’s create a new pen with a different width. Listing 10.4 creates a pen that’s 1 pixel wide (it does so by dividing the number of pixels we want—in this case 1—by the page resolution, which is given by DpiX). We draw the line again, this time specifying a red color.

Listing 10.4 Using the GraphicsUnit.Inch option with a pixel width
Pen redPen = new Pen(Color.Red, 1/g.DpiX);
g.PageUnit = GraphicsUnit.Inch;
g.DrawLine(Pens.Black, 0, 0, 2, 1);

Figure 10.6 shows the output from Listing 10.4.


Figure 10.6. Drawing with the GraphicsUnit.Inch option and a pixel width


We can also combine the use of page and device coordinates. In Listing 10.5 we transform page coordinates to 1 inch from the left and 0.5 inch from the top of the upper left corner of the client area. Our new page coordinate system has starting and ending points of (1, 0.5) and (3, 1.5), but the device coordinate system converts them to pixels. Hence the starting and ending points in device coordinates are (96, 48) and (288, 144), assuming a resolution of 96 dots per inch.

Listing 10.5 Combining page and device coordinates
Pen redPen = new Pen(Color.Red, 1/g.DpiX);
g.TranslateTransform(1, 0.5f);
g.PageUnit = GraphicsUnit.Inch;
g.DrawLine(redPen, 0, 0, 2, 1);

Figure 10.7 shows the output from Listing 10.5.




Figure 10.7. Combining page and device coordinates

Wednesday, February 13, 2008

Troubleshooting WPF Designer Load Failures

Hi,

Now that people have been kicking the tires of the WPF Designer for Visual Studio 2008 (aka "Cider). Here's a preview of the topic that will ship in the docs. Hopefully this will help out before frustration and despair set in.

Thanks,
Venugopal.

Monday, February 4, 2008

How Can I Get ItemsPanelTemplate Obeject Reference In Custom Control Class Itself?.

Hi,

I have faced complex problem during my ScrollPanel(I will post this ScrollPanel logic and advantage by shortly) CustomControl implementation. The actual problem is I couldn't get ItemsPanelTemplate object reference in control class itlsef. I found some solution in net, but those things are related to outside of control class only.

Then finally i found the soultion with the help of VisualTreeHelper class. Here is the code snippet.

private T FindItemsPanel(Visual visual)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
{
Visual child = VisualTreeHelper.GetChild(visual, i) as Visual;
if (child != null)
{
if (child is T && VisualTreeHelper.GetParent(child) is ItemsPresenter)
{
object temp = child;
return (T)temp;
}


T panel = FindItemsPanel(child);
if (panel != null)
{
object temp = panel;
return (T)temp; // return the panel up the call stack
}
}
}
return default(T);
}

But here also I had one problem like getting object reference after initialized my control. I had tried with OnInitialized method, and tried in constructor of my control class, but not use. Then finally found the solution with the help of OnLoaded event of my control class.

Like Below :

public ReflectionGallery()
{
this.Loaded += new RoutedEventHandler(ReflectionGallery_Loaded);
}



void ReflectionGallery_Loaded(object sender, RoutedEventArgs e)
{

//ItemsPanelObject is my own dependency property
ItemsPanelObject = FindItemsPanel(this);
}


This is my control template(Style)

<Style TargetType="{x:Type local:ReflectionGallery}" x:Key="{x:Type local:ReflectionGallery}">
<Setter Property="Template" Value="{StaticResource ReflectionGalleryTemplateKey}"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<local:ReflectionPanel Name="PART_ReflectionPanel" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>


Now we can use ItemsPanelObject property to play with custom panel of my ScrollPanel control.


I hope this will help to Custom Control authors like me :) :).


Please feel free to post your comments on this.

I will meet you with my ScrollPanel post. This might be very cool like Carousel panel.

Thanks,
Venugopal.


Wednesday, January 9, 2008

How Can I Get System Brushes List in WPF?.

For getting System brushes list, we need to use propertyinfo class.

Here i am creating ObservableCollection with object type as MyBrush.

public class ColorItemList: ObservableCollection
{
public
ColorItemList() : base()
{
Type type = typeof( Brushes );
foreach( PropertyInfo propertyInfo in type.GetProperties( BindingFlags.Public BindingFlags.Static ) )
{
if( propertyInfo.PropertyType == typeof( SolidColorBrush ) )
Add( new MyBrush( propertyInfo.Name, ( SolidColorBrush )propertyInfo.GetValue( null, null ) ) );
}
}
}

MyBrush.CS class should be like this.

public class MyBrush
{
private string m_name;
private SolidColorBrush m_brush;
public string Name
{
get
{
return m_name;
}
set
{ m_name = value;
}
}
public SolidColorBrush Brush
{
get
{
return m_brush;
}
}
public MyBrush(string name, SolidColorBrush brush )
{
m_name = name;
m_brush = brush;
Color color = brush.Color;
}
}

Now you can get System brushes list using our IEnumerable class MyBrushList.

I hope you may got idea. if not Please don't hesitate to post your comments here.

Saturday, January 5, 2008

How Can I Host WPF Controls In WinForms Application

First add references to the WPF namespaces (PresentationCore, PresentationFramework, UIAutomationProvider, UIAutomationTypes, and WindowsBase). Next create an instance of the ElementHost control and the control you wish to embed in the Windows Forms application and then hook that control up to the ElementHost control. Then simply add the ElementHost control to your Forms control collection:


ElementHost host = new ElementHost();
System.Windows.Controls.ListBox wpfListBox =
new System.Windows.Controls.ListBox();

for (int i = 0; i < 10; i++)
{
wpfListBox.Items.Add("Item " + i.ToString());
}

host.Dock = DockStyle.Fill;
host.Controls.Add(wpfListBox);
this.panel1.Controls.Add(host);

However, if you want to use XAML to describe the WPF control that you want to use in the Windows Forms application, you would need to add an Avalon UserControl item to your project. This will create a UserControl1.xaml file and a UserControl1.xaml.cs file. You can then modify the UserControl1.xaml file to contain whatever XAML you wish to describe your control. Then you would simply create an instance of this control and add it to the ElementHost control as in the above example:

ElementHost host = new ElementHost();
UserControl1 uc1 = new UserControl1();
host.Controls.Add(uc1);
host.Dock = DockStyle.Fill;
this.panel1.Controls.Add(host);

In addition, you will need to modify the project file because the Windows Application does not what to do with the XAML file. You will need to open the project file (.csproj, .vbproj, etc.) in an editor like Notepad and then scroll to the bottom.
You will see the following line:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
You will need to copy this line and paste it just below the above line and then change "CSharp" to "WinFX" so that the two lines look like:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildBinPath)\Microsoft.WinFx.targets" />
Now save this file and reload the project using VS and run the application.


Thanks,
Venugopal.