Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Monday, September 13, 2010

Posted by SAMAJ SHEKHAR

1”

Making Any Control Draggable in Silverlight & WPF


Introduction

Silverlight gives you easy access to make your User Controls come alive. For example you can make any control in Silverlight draggable. Here's how:

In your Code add a TranslateTransform inside your layout grid of your user control. The TranslateTransform will allow you to move your grid along the x and y coordinates of your application

Listing 1 - Adding the TranslateTransform to your control
<Grid x:Name="LayoutRoot" >
        <Grid.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform x:Name="LocalTranslateTransform"/>
            </TransformGroup>
        </Grid.RenderTransform>

Now we want to pick a control inside the UserControl to grab onto. In our sample we will use a Border control. Inside the Border control, we'll add mouse events to handle the various states of dragging with the mouse.

Listing 2 - Hooking up the mouse events to the Border control
<Border x:Name="myToolbar" MouseLeftButtonDown="OnToolbarClicked"
 MouseLeftButtonUp="OnToolbarReleased" MouseMove="OnToolbarMoving"  />
The Code

The XAML part was pretty simple. Now let's look at the code behind. All of the dragging functionality is handled by our 3 event handlers: OnToolbarClicked, OnToolbarReleased, and OnToolbarMoving. When we first click down on the border control, we need to record the initial offset point for our transform. We also need to set the state to mouseDownInToolbar to true to indicate we are dragging. Finally we need to set the mouse mode to capturing inside the border control.

Listing 3 - Handling the mousedown event inside the border
private void OnToolbarClicked(object sender, MouseButtonEventArgs e)
{
    mouseDownInToolbar = true;
    DragOffset = e.GetPosition(LayoutRoot);
    toolbarBorder.CaptureMouse();
}

While the mouse is in the mouseDownInToolbar state, we need to translate the position of the toolbar in reference to the position of the mouse. Listing 4 illustrates how we go about this. We get the position of the mouse relative to the main grid of the control. Then we change the TranslateTransform of the grid based on the new position of the mouse. We also need to offset the current mouse position by the original location of the mouse when we first clicked down in the control. Everytime we move the mouse, the new TranslateTransform will be computed and our control will move to the translated location. The mouse cursor will remain at the point when we first clicked the toolbar.

Listing 4 - handling the dragging of the control while the mouse is moving
private void OnToolbarMoving(object sender, MouseEventArgs e)
{
    if (mouseDownInToolbar)
    {
        // we want to move it based on the position of the mouse
        moveUserControl(e);
    }
}

private void moveUserControl (MouseEventArgs e)
{
    Point mousePos = e.GetPosition(LayoutRoot);
    Double newX = LocalTranslateTransform.X + (mousePos.X - DragOffset.X);
    Double newY = LocalTranslateTransform.Y + (mousePos.Y - DragOffset.Y);
    LocalTranslateTransform.X = newX;
    LocalTranslateTransform.Y = newY;
}

When the user unclicks the mouse, we need to stop the drag process. The MouseUp event handler will release the mouse capture and set the mouseDownInToolbar state to false. This will prevent the toolbar to continue to move as we drag the mouse around the screen.

Listing 5 - Handling Mouse Up when dragging the Toolbar
private void OnToolbarReleased(object sender, MouseButtonEventArgs e)
{
    mouseDownInToolbar = false;
    toolbarBorder.ReleaseMouseCapture();
}
Conclusion

Manipulating size and position of controls is fairly easy in Silverlight with the power of transforms. Dragging a control is accomplished using the TranslateTransform in conjunction with mouse events and functions. You can probably take this a step further and build your own docking framework. Anyway, drag yourself away from conventional controls in Windows and enjoy the power and flexibility of WPF in the browser with Silverlight.

Originally taken from Here
READ MORE - Making Any Control Draggable in Silverlight & WPF

Saturday, August 28, 2010

Posted by SAMAJ SHEKHAR

4

Introduction to using WP7 Accelerometer


This post is about introducing you Windows Phones Accelerometer (I have taken following contents from Charles Petzold's book "Programming Windows Phone 7 - Special Excerpt 2". The contents are Copyright of Microsoft and is used only for informational purpose). You can get more detailed information about using Accelerometer from above mentioned book, complete book is still to be released later this year.

Windows Phones contain an accelerometer — a small hardware device that essentially measures force, which elementary physics tells us is proportional to acceleration. When the phone is held still, the accelerometer responds to the force of gravity, so the accelerometer can tell your application the direction of the Earth relative to the phone. It is convenient to represent the accelerometer output as a vector in three-dimensional space. Vectors are commonly written in boldface, so the acceleration vector can be symbolized as (x, y, z). XNA defines a three-dimensional vector type; Silverlight does not.

While a three-dimensional point (x, y, z) indicates a particular location in space, the vector (x, y, z) encapsulates instead a direction and a magnitude. Obviously the point and the vector are related: The direction of the vector (x, y, z) is the direction from the point (0, 0, 0) to the point(x, y, z). But the vector (x, y, z) is definitely not the line from (0, 0, 0) to (x, y, z). It’s only the direction of that line. The magnitude of the vector (x, y, z) is calculable from the three-dimensional form of the Pythagorean Theorem:

Magnitude = Math.sqrt( Math.pow(x,2), Math.pow(y,2), Math.pow(z,2) )
where:
Math.sqrt() function returns the square root of a number
Math.pow() function returns a number raised to a power
For working with the accelerometer, you can imagine the phone as defining a threedimensional coordinate system. No matter how the phone is oriented, the positive Y axis points from the bottom of the phone (with the buttons) to the top, the positive X axis points from left to right.



When the phone is still, the accelerometer vector points towards the Earth. The magnitude is 1, meaning 1 g, which is the force of gravity on the earth's surface. When holding your phone in the upright position, the acceleration vector is (0, –1, 0), that is, straight down.

So lets start, To use the accelerometer, you’ll need a reference to the Microsoft.Devices.Sensors library, and a using directive for the Microsoft.Devices.Sensors namespace. In WMAppManifest.xml, you need
<Capability Name="ID_CAP_SENSORS">

You create an instance of the Accelerometer class, set an event handler for the
ReadingChanging event, and call Start. And then it gets a little tricky. Let’s take a look at a project named SilverlightAccelerometer project that simply displays the current reading in its content grid. A centered TextBlock is defined in the XAML.

<Grid x:Name="ContentGrid" Grid.Row="1">
    <TextBlock Name="txtblk"
     HorizontalAlignment="Center"
     VerticalAlignment="Center" />
</Grid>

This is a program that will display the accelerometer vector throughout its lifetime, so it creates the Accelerometer class in its constructor and calls Start:

public MainPage()
{
    InitializeComponent();
    Accelerometer acc = new Accelerometer();
    acc.ReadingChanged += OnAccelerometerReadingChanged;
    try
    {
        acc.Start();
    }
    catch (Exception exc)
    {
        txtblk.Text = exc.Message;
    }
}

The documentation warns that calling Start might raise an exception, so the program protects itself against that eventuality. These user-interface objects are not thread safe; they are not built to be accessed simultaneously from multiple threads. For this reason, Silverlight will not allow you to access a user-interface object from a non-UI thread.

This means that the OnAccelerometerReadingChanged method cannot directly access the TextBlock element to set a new value to its Text property. Fortunately, there’s a solution involving a class named Dispatcher defined in the System.Windows.Threading namespace. Through the Dispatcher class, you can post jobs from
a non-UI thread on a queue where they are later executed by the UI thread.

The Dispatcher class defines a method named CheckAccess that returns true if you can access a particular user interface object from the current thread. (The CheckAccess method is also duplicated by DependencyObject itself.) If an object can’t be accessed from the current thread, then Dispatcher provides two versions of a method named Invoke that you use to post the job to the UI thread.

The verbose version requires a delegate and a method defined in accordance with that delegate. The delegate (and method) should have no return value, but as many arguments as you need to do the job, in this case setting a string to the Text property of a TextBlock:
delegate void SetTextBlockTextDelegate(TextBlock txtblk, string text);
void SetTextBlockText(TextBlock txtblk, string text)
{
    txtblk.Text = text;
}
The OnAccelerometerReadingChanged is responsible for calling SetTextBlockText. It first makes use of CheckAccess to see if it can just call the SetTextBlockText method directly. If not, then the handler calls the BeginInvoke method. The first argument is an instantiation of the delegate with the SetTextBlockText method; this is followed by all the arguments that SetTextBlockText requires:
void OnAccelerometerReadingChanged(object sender, AccelerometerReadingEventArgs args)
{
    string str = String.Format("X = {0:F2}\n" +
    "Y = {1:F2}\n" +
    "Z = {2:F2}\n\n" +
    "Magnitude = {3:F2}\n\n" +
    "{4}",
    args.X, args.Y, args.Z,
    Math.Sqrt(args.X * args.X + args.Y * args.Y +
    args.Z * args.Z),
    args.Timestamp);
    if (txtblk.CheckAccess())
    {
        SetTextBlockText(txtblk, str);
    }
    else
    {
        txtblk.Dispatcher.BeginInvoke(new
        SetTextBlockTextDelegate(SetTextBlockText),
        txtblk, str);
    }
}
This is not too bad, but the need for the code to jump across threads has necessitated an additional method and a delegate. Is there a way to do the whole job right in the event handler?
Yes! The BeginInvoke method has an overload that accepts an Action delegate, which defines a method that has no return value and no arguments. You can create an anonymous method right in the BeginInvoke call. The complete code following the creation of the string object looks like this:
if (txtblk.CheckAccess())
{
    txtblk.Text = str;
}
else
{
    txtblk.Dispatcher.BeginInvoke(delegate()
        {
            txtblk.Text = str;
        });
}
The anonymous method begins with the keyword delegate and concludes with the curly
brace following the method body. The empty parentheses following the delegate keyword are not required.



The Windows Phone 7 emulator doesn’t contain any actual accelerometer, so it always reports a value of (0, 0, –1), which indicates the phone is lying on a flat surface:



READ MORE - Introduction to using WP7 Accelerometer

Wednesday, July 21, 2010

Posted by SAMAJ SHEKHAR

2

Cool Borderless Rounded WPF Form


Hi, recently i was making a small app that will allow me to create a Sidebar Gadget manifest (gadget.xml) by just entering various elements and properties on a form. It will generate the manifest file based on your input. Now first thing i had to decide was to take on win-form as my ui or the go with WPF. Well since WPF is new tech i ended up with WPF form.

Now i wanted my WPF to be good looking with a smooth round edge. First i tried different ways discussed on internet, but none sufficed my requirements. So i went down my own way and created a good looking form i wanted. Below is a snapshot.




















The method is simple, since i didn't wanted the default windows border so i set my WindowStyle="None" and to hide the corners protruding behind the border i set the AllowsTransparency="True" and Background="{x:Null}.
Now i warped my grid in a Border control and set CornerRadius to 12
 for all corners. Now for a Title Bar i added a Canvas control in the grid and inserted a Label and a button for Closing the form. (Actually the Button itself is a collection of two rectangles transformed to 45 Degree, simply X didn't looked good). Then in the End i adjusted the Border's Background to a Horizontal gradient with 3 stops to mix it with the Title bar. Following is the code.






















(Click on Image to Enlarge)



I know there are many ways to do this , this was mine.

Do write comments please...
READ MORE - Cool Borderless Rounded WPF Form