Archive for the ‘C#’ category

WPF: Simple Vista Image Viewer

September 25th, 2009

Preview of WPF Image Viewer

Download source code – 72.2 KB
Download sample app – 67.8 KB

What does it do?

This lightweight WPF UserControl will display a single image in a manner similar to the Windows Photo Gallery. It doesn’t manage more than one image in a gallery or slideshow fashion however, but it does:

  • Zoom In/Out both with the mouse and with a slider control
  • Pan the image with the mouse
  • Rotate the image clockwise or counter-clockwise 90 degrees
  • Keep the image fully visible in the display area when not in zoom mode

How can I use it?

You can use this image viewer in any WPF application with little effort since it’s built as a WPF UserControl. By leveraging the WPF Interoperability in WinForms it’s possible to use this in a Windows Forms application as well, see the article here for instructions on accomplishing that.

To get started using the control, download the source project from the above link. You can play around with the sample application to see an example of how to use the image viewer. The sample program simply provides a Window for the control and sets the path for the image to display; the control does all the rest.

To use the control in your own application you simply need to include the necessary source files in your own project or solution (CgsImageViewer.xaml(.cs), PanAndZoom.cs, and the images for the buttons). Once you’ve got them, you’ll begin by inserting the viewer into your XAML, like so:

<Window x:Class="ImageViewer.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:iv="clr-namespace:ImageViewer"
    Title="Image Viewer Sample" Height="418" Width="410">
    <Grid>
        <iv:CgsImageViewer x:Name="cgsImageViewer" />
    </Grid>
</Window>

This is just placing the image viewer in a window and giving it a name. Now to load up an image all that you need to do is provide a path to the image or a BitmapImage object. You can do this in the business code or in the XAML by means of a data binding. Here’s an example of setting the image in the business code:

cgsImageViewer.CurrentImagePath = @"c:\test images\cat-plans-your-doom.jpg";

That’s all you really need to know to use the image viewer. Continue on for some extra info.

Class Members you might want to know about:

  •  CurrentImage – Gets or sets the current BitmapImage used by the viewer.
  •  CurrentImagePath – Gets or sets a string representing the Uri to load an image from.
  •  ZoomLevel – Gets or sets a double representing the percentage to zoom.
  •  ScaleToFit – Resizes the image to fit within the visible bounds.
  •  RotateLeft – Rotates the image 90 degrees to the left and scales it to fit.
  •  RotateRight – Rotates the image 90 degrees to the right and scales it to fit.

(Note: The code for panning and zooming was found here)

A little background and explanation:

I wrote this control in a grand total of about two days, which included testing. It was written for use in a WPF project I’m currently working on where users needed to be able to preview graphic files inside the program. I decided to make something that could be re-used and would provide simple viewing capabilities.

So here you go. If you’ve used it and like it why not leave a comment or trackback. If you find any bugs or have some ideas to improve on it let me know. I’m always looking to make things better!

WPF: Bind Control Enabled to Checkbox Checked

July 23rd, 2009

This is a simple example of a nifty use of binding in WPF.

Say you have an element in your application such as a TextBox, ComboBox, or some RadioButtons that you want to keep disabled to the user unless the user checks a box. You may even want to disable a whole section of controls contained inside of a StackPanel or DockPanel.

Everything enabled

To accomplish this you bind the IsEnabled property of the target control (in this case a ComboBox) to the IsChecked property of the CheckBox.

XAML:

<StackPanel>
    <CheckBox x:Name="chkEnableBackup">Run Backup Sets</CheckBox>
 
    <StackPanel Orientation="Horizontal">
        <Label Margin="12,0,0,0">Run backup every</Label>
        <ComboBox Width="70" SelectedIndex="0"
          IsEnabled="{Binding ElementName=chkEnableBackup, Path=IsChecked}">
            <ComboBoxItem>Minute</ComboBoxItem>
            <ComboBoxItem>Hour</ComboBoxItem>
            <ComboBoxItem>Day</ComboBoxItem>
        </ComboBox>
    </StackPanel>
</StackPanel>

That’s it! Our result is that when the box is not checked the control is disabled.

Control disabled!

WPF: Center Child Window

May 7th, 2009

Here’s a method I’ve found for centering a window to either its parent or the main window for the application, in WPF. It’s not too far different from how you do it in WinForms.

For the child window set it’s WindowStartupLocation to “CenterOwner.” This will cause it to show in the center of the owning Window.

<Window x:Class="WpfApplication1.TestChild"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="TestChild" Height="300" Width="300"
 
    WindowStartupLocation="CenterOwner">

Now all that’s left to do is set its owner before displaying it. If the code you’re using to display the window is running inside of a Window class, then you can just use this.

TestChild testWindow = new TestChild();
testWindow.Owner = this;
testWindow.Show();

This isn’t always the case however, sometimes you need to display the child window from code running on a page or a user control. In this case you want the child window to be centered to the main window of the application.

TestChild testWindow = new TestChild();
testWindow.Owner = Application.Current.MainWindow;
testWindow.Show();

C#: Detect If You’re Running on the Server

April 27th, 2009

If you ever need to detect whether your code is running on the machine that you’re talking to through IP (a server application for example), and you know the IP address for the remote machine, then this code may come in handy. It was originally written by my buddy Erin for a project we both worked on.

using System.Net;
 
private bool CheckIfServer(IPAddress serverIP)
{
    // Get all addresses assigned to this machine
    List<IPAddress> ipAddresses = new List<IPAddress>();
    ipAddresses.AddRange(Dns.GetHostAddresses(Dns.GetHostName()));
 
    // If desirable, also include the loopback adapter
    ipAddresses.Add(IPAddress.Loopback);
 
    // Detect if this machine contains the IP for the remote server
    // Note: This uses a Lambda Expression, which is only available .Net 3.x
    return ipAddresses.Exists(i => i.ToString() == serverIP.ToString());
}

If you don’t know the IP Address for your remote server you can easily get it using the server’s host name like this:

IPAddress[] addresses = Dns.GetHostAddresses("remote_host_address");

This returns an IPAddress[] which includes all the resolved addresses for that host.

C#: Lower Case All XML Tags with Regex

April 24th, 2009

Sometimes when accepting an XML document from an uncontrolled source using Linq to XML, it’s useful to convert all tags and attributes to lower case before processing the XML. This is because Linq to XML is case-sensitive and you can’t always rely on the program producing the XML to follow your casing standard for elements and attributes.

So here’s a quick and dirty single line of code that will accomplish just this in C# using a regular expression:

Regex.Replace(
    xml, 
    @"<[^<>]+>",
    m => { return m.Value.ToLower(); }, 
    RegexOptions.Multiline | RegexOptions.Singleline);

And here’s that functionality all nice and wrapped up inside of an extension for XElement:

public static class XElementExt
{
    public static string LowerCaseTags(string xml)
    {
        return Regex.Replace(
            xml,
            @"<[^<>]+>",
            m => { return m.Value.ToLower(); },
            RegexOptions.Multiline | RegexOptions.Singleline);
    }
}

Note: The Regex class is defined in System.Text.RegularExpressions

Here’s an example of the resulting affect.

Before:

<ParentNode>
   <ChildItem TestAttribute="ValueCasing" >
	This text Will not Be Harmed!
   </ChildItem>
</ParentNode>

After:

<parentnode>
   <childitem testattribute="valuecasing" >
	This text Will not Be Harmed!
   </childitem>
</parentnode>

You’ll notice that with this method all text within element tags is converted to lower case. This means that attribute values will lose any special casing they may have had, which may or may not be a problem for what you’re doing.