Tag WPF

Will it Blend: Wrapping the Text on Silverlight Chart Legends

In the course of my building our ROI app, I was trying to figure out how to wrap the legends of charts when the text gets too long.

This is what I get with the default chart.

image

You’ll see here, there’s a lot of waste of space for the legend when what I really want to see is more of the chart.  So first thing we’ll do is fix the width of the chart. To do that, Right Click on the chart, Edit Template then depending on whether you’ve already been fiddling with your chart template, either Edit Current or Edit a Copy

2010-11-30 13h39_21

When you expand the template, you’ll see a grid within the grid that contains both the chart and the legend.

2010-11-30 13h42_32

You’ll notice that the grid is split into two, a star sized column and an auto sized one. Since autosizing will adapt the column size to the content, we’ll need to change this to star sized as well. You can do that by clicking on the icon and change it to the unlocked lock symbol.

2010-11-30 14h11_07

Now, you should be able to click on the triangle and resize the columns to your desired width ratios.

2010-11-30 14h12_46

You’ll notice that when you do this, your legend area won’t have as much space as before and since the legend items aren’t formatted to wrap by default, the text gets cropped if you have long lines of text.

2010-11-30 14h14_00

Return to the scope of the user control by clicking on this icon in your Objects and Timeline panel

2010-11-30 14h17_00

Find one of your ColumnSeries (or whatever data series your chart is using) Right-click->Edit Additional Templates –> Edit LegendItemStyle –> Edit a Copy

2010-11-30 14h19_22

Give your style a name, and choose where to define this style. This depends on where you will be using this style, if it’s only in this page, then you can choose document. If there are other pages, you think you’ll be using this style in, choose Application. If you want to be able to reuse this style in other applications ,choose Resource Dictionary, choose an existing one or create a new one if you don’t have one yet. This stores the style in a separate file which you can then later on import to your other projects.

2010-11-30 14h23_18

Clicking on OK should then bring your designer to to the LegendItem template designer. If you expand the StackPanel, you’ll see that we have the Rectangle and Title elements. If you look into the xaml code, you’ll see that the Title element is template-bound to a property called Content.

2010-11-30 14h31_26

In my case, since I know that the legend will only represent text content, I can simple delete the title element, replace it with a Textblock object and apply the same bindings. I can do that by first selecting the textbox, search for the text property in the search box of the Properties panel, then clicking on the small square beside the property to access advanced options.

2010-11-30 14h35_30

We select Template Binding –> Content

2010-11-30 14h38_51

One last thing to do is set the width of the TextBox since it’s currently auto sized and we can’t currently set the width to take up the rest of the unoccupied horizontal stackpanel space. Smile If you want your legend to scale dynamically, you’ll need to change the stackpanel into a grid. To do this, right-click on the StackPanel in your Objects and Timeline panel –> Change Layout Type –> and select Grid

2010-11-30 14h46_38

After this step, check on your Rectangle, most likely, the Width and Height properties will be reset to auto so you’ll want to give this a size.

2010-11-30 15h01_40-

For the grid itself, it’s Height and Width gets fixed so we’ll want to reset this to auto so the grid is free to resize as it’s content or container feels necessary.

2010-11-30 15h06_16

Now we can add a grid line by clicking on the top portion of our grid, and right after where the Rectangle ends:

2010-11-30 14h49_09

then toggle the grid property (by clicking on the lock icon) until we get Pixel sized.

2010-11-30 14h52_22

We can leave the other column at star sized so it’ll take up the rest of the available space.

2010-11-30 14h51_56

With the TextBox selected, make sure the Width and Height  is set to auto (if there is a value, you can use the button on the right of the field to set to auto), the HorizontalAlignment and VerticalAlignment are set to Justified and the margins are set to the distance you want.

2010-11-30 14h55_05

Now when you go back up to the UserControl scope, you’ll see the TextWrap in effect. Looking at this though, I might want to change the alignment/margins so that the rectangle is aligned to top instead of in the middle just to make it look nicer.

2010-11-30 15h11_13

To go back to editing the template, right click on the ColumnSeries –> Edit Additional Templates –> Edit Current –> Edit LegendItemStyle

2010-11-30 15h12_35

In my case, I chose top aligned with a bit of a top margin.

2010-11-30 15h14_27

Going back out to the UserControl scope, we’ll be able to see the effect.

2010-11-30 15h18_33

You can play around with how you want your legend to look and once your satisfied, it’s time to apply the style to the other series’. No you don’t to do that whole set of steps for each of them so don’t worry. Right click on the other column series-> Edit Additional Templates –> Edit LegendItemStyle –> and this time select ApplyResource and you should see the style you created in the previous steps and click on that. In my case, I named the style LegendItemStyle.

2010-11-30 15h20_05

You’ll notice your legend automatically format itself the same way the previous column series did.

2010-11-30 15h22_34

And that’s it!

Will it Blend: Custom Scrollbar in WPF

DISCLAIMER: I write this post more for myself because I tend to forget how to do things. There can very well be other proper ways of doing this, but this is the “good enough” solution, at least for me. Smile

I was playing around with WPF again since it’s been a while. I wanted to customize the scrollbar and I found it was quite a task. I finally figured out a simple way of doing it.

The look I wanted was a simple, thin, vertical bar (I guess you could do the same with the horizontal bar.

image

1. So we start with a ScrollViewer that contains a RichTextBox(or whatever you want)

image image

2. Now we proceed to EditTemplate –> Edit a Copy.

2010-07-11 16h48_17

3. You’re probably already familiar with this dialog box. Give your template a Name when you click okay, by default, it’ll add this to your window’s xaml. But if you want to later on reuse this template, choose the option to define it in a Resource dictionary. Later on, all you’ll have to do is add that resource dictionary to your project and you’ll be able to apply the style to your ScrollViewer.

2010-07-11 16h50_39

4. We’ll fix the VerticalScrollBar in this sample but you can very well do the same for HorizontalScrollBar. To start, right-click on PART_VerticalScrollBar and click on EditTemplate –> Edit a Copy. Again, you’ll be asked to select a name and where you want to save this style. This time, we’re editing the ScrollBar component (previously was the entire ScrollViewer).

2010-07-11 16h55_41

5. If you expand the template that you’re presented with, you’ll see the elements below. In my case, I want to delete the two RepeatButtons since clicking anywhere above and below the Thumb more or less does the same thing.

2010-07-11 16h56_50

5a. But lets say you wanted to edit the buttons, what we do, is draw out what we want the button to look like anywhere on the canvas. We’ll delete this later on. Here, we have a Grid that contains our desired button template.

2010-07-11 17h06_07

5b. What we’ll do now is right-click on the grid and select Make Into Control. A dialog box will appear that will ask you to select which control you want this grid to magically turn into. You’ll notice above that the buttons for scrolling up and down are RepeatButtons, so we can type into the search box to find the component, click to select and we’ll name it into something we will recognize later on, in my case, ScrollUpButton.

2010-07-11 17h10_00

5c. Now we’re editing the RepeatButton template. We can go ahead and delete the automatically generated ContentPresenter since we don’t need any content in our template.

2010-07-11 17h10_42

5d. You’ll notice that you can also go into the states tab to edit the look of your button on different states.

2010-07-11 17h12_24

5e. Once you’re done editing, you can go back to the Objects and Timeline tab and click on this button that will take you back to the ScrollbarTemplate

image

5f. Now to apply the style, select the first RepeatButton –> Edit Template –> Apply Resource –> ScrollUpButton (or whatever you named your template)

2010-07-11 17h16_34

5g. You’ll now see the button with the style you’ve defined. Now remember to delete that Grid turned Repeat button that we used to create the style or else, it’ll become part of your template/application Smile

image

6. Like I said, I’m deleting my up and down buttons because I don’t want them. You’ll notice that the grid this ScrollBar was defined in has Rows that hold the buttons and the thumb / track. I’ll need to delete the extra rows since I don’t need them now and I want the thumb and vertical bar to occupy the entire height. I tried deleting this through the designer but it only wreaked havoc (might be a user error) but I found the safest way to do this is to delete from the XAML code.  Click on this button in the upper right corner of your design canvas to show the xaml editor. (Now you know why I said XAML typing instead of XAML editing)

image

7. What I’ll do now is delete the 1st and 3rd row definitions.

2010-07-11 17h21_17

8. Now I’ll see my scrollbar occupy the full height.

image

9. Next, I want to change the look of the ScrollBar’s thumb. You’ll see that the type of component this is is a Thumb. So we can do as we did with the Repeat button to style this. Make into Control only works on single objects so if you have several objects you want to include in your template, just right-click –> Group Into –> Grid to make them one.

2010-07-11 17h33_27

10. Now you can follow the steps in 5b but this time, instead of RepeatButton, we select Thumb in the Make Into Control dialog.

2010-07-11 17h37_34

11. Now continue with 5f to go back to ScrollBar template editing and apply the template to the Thumb object. You’ll now see our ScrollBar has changed. Again, remember to delete that extra thumb that we used to create the style.

image

12. One last thing. Maybe you don’t want your ScrollBar to be as thick as this. So using the button in 5e, go back up to the ScrollViewer template. With the PART_VerticalScrollBar selected, go to the Properties tab and scroll down to the Style property. You’ll see that it’s highlighted in green which means it’s being bound to a local resource.  

2010-07-11 17h44_18

13. Click on Edit Resource

2010-07-11 17h45_59

14. You’ll then see our style, and if with it selected, you scroll down the Properties tab to the Width property, again you’ll see that the Width property is bound.

image

15. Click on the Advanced Options button (that little square) and select Reset. You should then be able to put in whatever width you want.

2010-07-11 17h50_49

16. Now when you click on the button in 5e. (Return scope button) it actually takes you to the topmost level which is the window. So you’ll have to do an Edit Template… on the ScrollViewer again to edit the ScrollViewerTemplate. (By the way, I’ve edited my Thumb template to make it look alright with a Width of 5, i.e., change the width of the topmost grid in the template to 5 and fixed the components inside to make it look good).

You’ll notice that the second column in the grid is set to auto-sized so you’ll want to click on that icon till it says pixel sized (locked lock)

2010-07-11 18h05_37

17. With the handle selected (that inverted triangle there) you can now set the width property to what fits your template.

image

Now if you return scope to window, (5e), and run your app, you’ll now see your fully functional and newly styled ScrollViewer.

2010-07-11 18h11_04

hmm.. looks like there’s one more property you need to set. With the PART_VerticalScrollbar selected, set the Background property to No brush.

2010-07-11 18h13_05

This is the effect you will get. Note, I’ve also set the RichTextBox borders to zero to remove all borders.

2010-07-11 18h17_06

And that’s it!

TechFriday: iPadding V1 – The Designer Story

imageWith the whole iPad buzz going around last week, I decided to build last friday’s TechFriday app around the theme.

Introducing iPadding v1! It’s basically a WPF application that allows you to drag and drop shortcuts onto the screen and save it for when it’s presentation time. My desktop is constantly cluttered and as much as I’d like to use the hide desktop icons features, I do want some shortcuts readily available. Even with the pinning feature of Windows 7, I just end up with a cluttered task bark instead Sad What I’ve been doing till now is creating a folder with the shortcuts of everything I want to show so i just have that pinned (or open by default) onto my taskbar.

So for TechFriday, I decided to make this little app that will store shortcuts in a window that looks like the iPad (or should i say P88?).

Version 1 includes the following features:

  • Drag & Drop items onto the screen
  • Click and Delete shortcuts that you want removed
  • Double-clicking to start an application
  • ClickOnce deployment enabling ease of deployment and distributing updates
  • and of course, clicking the button formerly know as the start button to save your shortcuts and shut down Smile

You can check out the application at http://bit.ly/b7893s and explore the source code here.

How I did it?

iPadding States

If you open up the project you’ll find the following state groups. (The third state is currently not supported in this release Smile)

image

The iPadLoading state simple sets the opacity of a canvas with the “broken window” logo to 100% while the iPadLoaded state does the reverse.

image

iPadding Components

For this version, we only have two major components to the app: icApps and btnStart

Let’s start with the btnStart as it is the easiest. This control is basically a styled button.

1. Start by adding a button onto the screen, then right-clicking, Edit Template –> Edit a Copy

image

You’ll then be prompted with a dialog box that will allow you to specify properties of this style. First is the Name, second is where you want to define the style in. The default is set to This Document which means the style will only be visible in this screen/page/usercontrol. Application will allow the style to be visible to the other pages/windows/usercontrols in the application. You can also select Resource dictionary to put the style in a separate file altogether and allow you to import the Resource Dictionary along with all the styles defined in it in other projects and applications.

image

 

For this button style, I made use of images to for 2 of the different button states: MouseOver and Normal.

image

The default style of the button contains the chrome and a ContentPresenter. The ContentPresenter is basically where Button.Content will be displayed. If you’ve been playing with WPF/Silverlight, you’ll know that you can not only assign text to as button contents, but images, videos and other controls as well.

In this case, I just want a simple image, so I can go ahead and delete the default contents and replace it with a grid that contains my button images. In this case, I added 2 images, one to depict the button in Normal state, and another on MouseOver state.

When you click on a state, you’ll notice the state recording turns on.Once this is so, you can start changing properties of your design elements to reflect your desired look.

imageimage

Now we’re pretty much done with the StartButton design. Let’s put in a stub where our developer can plug in the code to make the app function as it is supposed to. To do this, let’s first return to the Window Scope

image

Next, while the button is selected, go to the properties tab an click on events.

image

Once the tab is activated, you can type in the method name you want called on the Click event

image

Doing this will activate the XAML editor in Blend and automatically insert the method stub for you or your developer to fill in once you are ready to start filling in the application logic. Let’s leave this for now and go on to the next component.

image

The next control is icApps is a styled ItemsControl that will contain all the apps that you drag and drop into the window. Let’s first go to our Asset Library and drop in the ItemsControl onto our Window. You might want to drop it into a Grid to fix the layout.

image

Next, we need to think about how we want to layout the items in our control. If you look at the iPhone, the apps are actually lined up in a 4 x 5 grid. However, since in the future, I’d like to be able to resize the screen and have the apps line up depending on the space, I’ll use a WrapPanel to manage the layout. To do this, I’ll right-click on the ItemsControl –> Edit Additional Templates –> Edit Layout of Items – >Edit a Copy. Again this will bring you a dialog box that will allow you to name and specify where you want your style created.

image

You’ll notice that the default layout is a StackPanel, but we’ll go ahead and change this into a WrapPanel.

image

You might also want to ensure that the ScrollBarVisibilities are properly set. I’ll be disabling scrolling for this version till I figure out how I want to page / scroll through my items.

image

Now that we have the layout set, we’ll now take a look at the template for generated items. So same as before, right-click on the ItemsControl -> Edit Additional Templates –> Edit Generated Items –> Edit a Copy. If you’re wondering why it’s “Edit a Copy”, WPF controls come with default templates that developers and designers can easily replace but because Blend needs to have a fall back in cases of new controls, the default templates are stored somewhere and are read-only for us. But we can always create our own style and set it as a default for all the controls in our project by selecting Apply to All in the Create Style Resource dialog.

I want the Apps to be visualize as buttons that can get focus when clicked so that the users can delete them if he chooses to, and launch the application when double clicked. I don’t want to recreate a control as the Button control can pretty much do what I need it to do. So what I’ll do in my data template is add a 120×120 grid to constrain the button size, and put a button inside and style it as I want and for this I’ve created a style called AppButton style. that has the following:

imageYou’ll notice that since I’m styling a button, the template already comes with the common button states such as MouseOver and FocusStates. This will make it much easier for me to fix my controls visuals through states instead of having to code it all up myself.

If you look at the object tree, I have an image will I will later on show how I tie up to the Icon of whatever shortcut is dragged into my app. I have a text block that will also display the name of that shortcut, and two rectangles that will basically be my MouseOverVisual and FocusVisual. Both these visuals have an opacity of 0% by default, and I simply edit the corresponding states to set the opacity to 100%.

I mentioned that for the image and text block, I wanted it to be bound to whatever the icon and name was used in the shortcut dragged into the app. Later on we’ll be using the ShellObject defined in the http://code.msdn.microsoft.com/WindowsAPICodePack The ShellObject data object has quite a number of properties but the one I’m intersted in would be Thumbnail, which is an Icon object which in turn has a MediumBitmapSource (medium because we’re looking at displaying bigger icons than the ones we see in details view of explorer) and Name, which will hold the filename on the shortcut.

As a designer, all I care about would be that those two properties of the data object will be present when the time comes. I can use data binding to link the properties of the data object with properties in my UI.

First off is the TextBlock. With the the TextBlock selected, I’ll head over to the properties panel and look for the text property since this is what I want to bind to the Name property of the data object. I can do so by clicking on the button right beside the Text textbox.

image

I’ll then select Data Binding.

image

You can data bind this the Text property to virtually anything as you’ll see in the dialog box that pops up, from data fields, to other elements properties. In this case, since we don’t have access to our data objects just yet, I’ll go straight to Explicit Data Context and tick the “Use a custom path expression” and put in the Name property. Again as a designer, I don’t have to care where that value comes from but i know that whatever data object is bound to this button, I’ll get access to a property called Name that will hold the name of the application or shortcut of the app I want to run.

image

I’ll do the same for the img object with the source property. This time, I’m binding it to “Thumbnail.MediumBitmapSource” since my developer tells me, there’s an existing object that we can use and that property is going to give me the filename of the icon i can use in my button.

image

Now that’s done, let’s help out our developer a little bit.We’ve decided that the behavior of this app is such that if a button is clicked, it’ll bring focus to that button. This is already the default behavior of a button and since we’ve only styled a button and not made our own, we won’t have to worry about building that behavior. The next behavior is that when double clicked, it runs the application associated with it. To do this, let’s exit scope one level up to the AppButton. We can either do as we did previously by clicking on the up arrow imageor by clicking AppButton on the bread crumb bar at the top of the XAML designer page: image 

With the AppButton selected, we’ll go to the events tab imageon the Properties page, go to MouseDoubleClick and type in a name of method that will hold the code to run the shortcut associated to the button. imageOnce we press enter, we’ll be brought to the code behind and we can write a little note to our developer to put in that piece of code here. If as a designer, later on you feel that it’ll be better to have the application run at a different event, you can simply move that method name to another event in the events list, and your developer won’t have to change their code.

image

Once that’s done, we can exit again till we’re all the way up on the window level. What we have done is basically create an ItemsControl with our custom style that displays a square button and a text block (as well as some visuals for mouse over and focus states). We’ve styled these buttons in such a way that the images and textblocks are bound to properties Name and Thumbnail.MediumBitmapSource. The idea here is that our developer will eventually bind this ItemsControl with a list of ShellObjects which we are told have those properties. Each shell object will be bound to a generated item with the template we defined. We’ve also created a method for our developer to implement that runs the associated application when the button is double clicked.

Next post will cover the developer portion of this application. Smile For now, you can download and try out the application on http://www.badgorilla.net/ipadding

Making Your Win7 JumpLists Trigger on the Same Application Instance

As promised in my previous post, I’ll be talking about how to create jumplist integrated single instance applications, much like how Outlook, Windows Media Player.

At first, i thought it would need to involve a bit of windows messaging but then I found this blog post that details how to create single instance WPF applications. I rewrote our sample from the previous post to adopt this model. I based my code on the post so I recommend reading that post first to have a better understanding of how we are creating this single instance application.

Explaining a bit what is going on here, we basically have 3 major classes:

image

The SingleInstanceManager, as the name implies, manages the instances of your application. If you take a look at the code, basically it creates an instance of your application if it is an initial startup. When a next instance is triggered to start up, it activates the the MainWindow through Win7Application and processes any arguments passed in the triggering of the subsequent instances.

Win7Application is basically our replacement for App.xaml because we want to be able to control when we activate the MainWindow of our application. We also process any arguments of our application in this class.

  public void ProcessArgs(string[] args, bool isFirstInstance)
        {
            if (args.Length > 0)
            {
                if (isFirstInstance)
                    AppWindow.initState = args[0];
                else
                    AppWindow.updateState(args[0]);
            }

        }

If you look at the ProcessArgs method in the sample attached, we’re basically setting an initial state (initState) property to the value of the argument as this is expected from the jumplists we have defined in my previous post. If this is not the first instance, we call the updateState() method which I have exposed as a public method in the MainWindow class. 

These are basically the changes I made to MainWindow.xaml.cs:

        private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {

            WindowJumpList = JumpList.CreateJumpList();
            initializeJumplist();
            if (initState != null)
                updateState(initState);

        }
        public  void updateState(string state)
        {
            ExtendedVisualStateManager.GoToElementState(LayoutRoot, state, true);

        }

You can download the source here:

Managing WPF Screens with Windows 7 Jumplists and the Visual State Manager

We’re having our Singapore launch of Windows 7 this November and in honor of that, I’ll be devoting my upcoming (and long overdue) TechFridays to everything Windows 7. For this post, I’ll be talking about how you can use the Visual State Manager for WPF to manage the different screen states in your application in conjunction with your Windows 7 Jumplists.

Before we start, make sure you have the following downloaded:

1. WPF Toolkit – This enables VSM support in current WPF projects

2. http://code.msdn.microsoft.com/WindowsAPICodePack – provides managed wrappers that allow you to easily incorporate Windows 7 JumpLists into your application

* make sure you add references to the above binaries and your set to go.

If you’re not familiar with the Visual State Manager, you can read http://windowsclient.net/wpf/wpf35/wpf-35sp1-toolkit-visual-state-manager-overview.aspx for a brief overview.

What I have is an application with several screens grouped into panels. I also have a visual state group “ScreenStates” where i have 3 states, one for each screen.

image

This should make for easier screen management. You can make use of Blend behaviors to activate these states on the click of the corresponding navigation button / link. If you open up the Behaviors tab in the asset library, you’ll find the GoToStateAction that you can click and drag onto the appropriate control that you want to trigger the state activation.

image

In the screen below, I added the behavior to my GalleryButton. On the properties panel, you’ll see that you can set the StateName you want to activate on the trigger, in this case, the GalleryButton’s Click event.

image

Next we we want to enable Windows 7 Jumplists in our application. Windows 7 is all about helping users become more efficient and one of the features that enable this is the jumplist. Below is a screenshot of Outlook’s jumplists. The application basically exposes tasks that would normally take a few clicks to get to so instead of having to spend the time starting the app and clicking the appropriate menus/options, you jump straight into the screen you want.

image

Below is one way you can integrate jumplists into the app we are building. First, you’ll need to define and initialize a few variables we will be needing to manage the jumplist: the Jumplist itself, and the folder where the assembly is executing.

        private JumpList WindowJumpList;
        string executableFolder;

	private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e)
	{
			// TODO: Add event handler implementation here.
            WindowJumpList = JumpList.CreateJumpList();
            executableFolder = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            initializeJumplist();
            string[] arguments = Environment.GetCommandLineArgs();
            if (arguments.Length > 1)
            {
                ProcessArguments(arguments[1]);
            }
	}

The following code then initializes the jumplist. Note that the tasks are shell links to the application executable, with the state names of our screens as the arguments. This will make it easier later on to process the arguments and activate the appropriate screen.

image

The last method is the ProcessArguments method. There is a slight kink in the VisualStateManager that won’t allow you to “go to state” as you normally would unless the target is a UserControl. In this case, we had to use a work around which i found here

image

when you compile and run your app, you’ll see the following jumplist tasks and will be able to activate the corresponding screens straight from the jumplist.

image

image

You can download and try out the code here:

This version launches a new instance every time you click on a task on the jumplist. In my next post, I’ll post a sample on how to create jumplist enabled single instance WPF applications. Till next time!

Tech Friday: The Orientator

I was thinking of an app to build for tech Friday and I remember running in to @willyfoo the other day. He mentioned he needed an application that would read in EXIF data from photographs and rotate them based on the orientation meta tag. It was quite a good exercise cause it allowed me to play around with a few things.

 

Problem 1: EXIF what?

Although I play around with photography once in a while (I bought a camera last year and I haven’t put any serious effort into it just yet), there are a few concepts which I have yet to understand. So apparently, cameras have a way of storing meta data into the photos you take. Some cameras store what its orientation is when you take a picture. So today, I brought my camera to work and took a few photographs as test photos. I found an existing library on CodeProject that will allow you to read EXIF data from photos called ExifLib.

So now, I can extract the data. The next step was understanding what code means what. http://www.impulseadventure.com/photo/exif-orientation.html gives a graphical explanation for the values of the Orientation metadata.

Problem 2: UI

To be honest, this is something that really needs to be thought through. I am guessing traditional applications would have a UI such as this that will allow you to select a file you want to “fix”. But then I thought, what if I wanted to do a batch job? I guess I could then select a directory. And then I remembered the challenge I had when I dealt with photos when uploading to facebook where my photos aren’t always in the same directory.

image

I then remembered a tweet by @MSExpression pointing to a blog post by kirupa where he talks about how you can enable drag & drop onto WPF components. So that is settled, Drag & Drop. I built a simple UI with a ListBox where you can drag your files to and an Image component where you can preview the rotated image.

image

There might be cases when the application messes up the auto orienting and you’d rather do it yourself manually. The UI allows you to select/de-select the files you want to save changes to. I have to say, it’s not the prettiest or most intuitive way to do it but I am not creative so this will have to do.

Problem 3: Preserving EXIF Data

I had originally thought it would be as easy as

     1  Bitmap bmPhoto = new Bitmap(filePath);

    2  bmPhoto.RotateFlip(RotateFlipType.Rotate180FlipNone);

but I was wrong. First, I realized that although it would successfully rotate the image, it would also bloat up the file (as it was saved without compression) plus, it would lose all the EXIF data the photos had. I don’t think this is something that @willyfoo would have wanted ^_^. So I dug around and found this post that showed you how to resize and manipulate jpegs while preserving the metadata. I did a bit of trimming as the code had stuff to resize the image, which I didn’t want to do for this round. One issue though, is because it encodes the bitmap using some parameters that i can’t figure out just yet (am just lazy too :p) It bloats the file up by a bit.

Problem 4: Saving Changes

Because my UI shows a preview of the image that was rotated, I got some errors where “the file is being used by a process” once I loaded them up into the application and tried to rename/delete them. This post on the msdn forum showed the fix for this.

You can download the code here:

Issues:

The application is functional but there is definitely a lot of room for improvement :)

1. Design – I think this application can be a lot nicer looking if I actually spend time on it. There’s a lot the WPF platform can do to “jazz up” the look and feel of the UI. I think my biggest challenge right now is coming up with a concept that would be cool looking enough :p

2. I’m not sure what happens if I drag&drop none images into the application. This line was supposed to take care of that:

 

    1             if (e.Data.GetDataPresent(DataFormats.Bitmap))

    2             {

    3                 ///some code here

    4             }

But for some reason, files I drag&drop into the app don’t get recognized as a Bitmap. I had to use DataFormats.FileDrop instead.

3. Bloating of image. As I mentioned in problem 3, I’m not very familiar with how encoding works so the app actually bloats the image size quite a bit. I think the following lines take care of the encoding, but when I try to step down on the encParm, it makes the image size smaller than the source. I figured, bigger is better.

    1                 System.Drawing.Imaging.Encoder enc = System.Drawing.Imaging.Encoder.Quality;

    2                 System.Drawing.Imaging.EncoderParameters encParms = new EncoderParameters(1);

    3                 System.Drawing.Imaging.EncoderParameter encParm = new EncoderParameter(enc,100L);

    4                 encParms.Param[0] = encParm;

    5                 ImageCodecInfo[] codecInfo = ImageCodecInfo.GetImageEncoders();

    6                 ImageCodecInfo codecInfoJpeg = codecInfo[1];

 

That’s it for now, until next Tech Friday!

Understanding Prism V2

Here are some videos on Channel 9 that walk through building an application using the Composite Application Guidance for WPF and Silverlight

Creating Modular Applications
Visual Composition
Implementing Views and Services
Decoupled Communication

Professional Developer Conference 2008

For those of us who aren’t able to attend this year’s Professional Developer Conference, the good news is, all the content they’re delivering will be available online through the site http://www.microsoftpdc.com This feed (http://channel9.msdn.com/posts/pdc2008/RSS/?tag=videos) will give you all the sessions that have been recorded and posted on Channel 9 (it’s a lot of content!) I highly recommend watching the Keynotes, especially the Day 2 Keynote (Day Two #1 – Ray Ozzie, Steven Sinofsky, Scott Guthrie and David Treadwell) where they showcase all the cool stuff that Microsoft is coming out with very soon. Very exciting stuff!

You just have to love technology. :)

Copyright © Aimee Gurl…
for as long as i can remember, technology has always fascinated me

Built on Notes Blog Core
Powered by WordPress