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

Friday, March 29, 2013

ChangeAwareContentControl–How to know when the content changes in a ContentControl

I am working on an application where I have a ContentControl, and I need to know when the content changes. My initial thought was to add an event handler for the ContentChanged event. I came to find out that the ContentControl does not fire a ContentChanged event.

My solution was to create a control derived from content control that fires that particular event. It is working quite nicely, so I thought I would share. I hope it helps you out. It’s a small amount of code, but it does the trick.

    public class ChangeAwareContentControl : ContentControl
{
static ChangeAwareContentControl()
{
ContentProperty.OverrideMetadata(
typeof(ChangeAwareContentControl),
new FrameworkPropertyMetadata(
new PropertyChangedCallback(OnContentChanged)));
}

private static void OnContentChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
ChangeAwareContentControl mcc = d as ChangeAwareContentControl;
if (mcc.ContentChanged != null)
{
DependencyPropertyChangedEventArgs args
=
new DependencyPropertyChangedEventArgs(
ContentProperty, e.OldValue, e.NewValue);
mcc.ContentChanged(mcc, args);
}
}

public event DependencyPropertyChangedEventHandler ContentChanged;
}


Here is how you use it in xaml.



<controls:ChangeAwareContentControl ContentChanged="ContenChangedHandler"/>


Thursday, March 28, 2013

BitmapImage.BeginInit()

A very common error new UI developers make is trying to create new BitmapImages without properly initializing them.

All property changes made to a BitmapImage must be made between the BeginInit() and EndInit() calls. Every property change made after the EndInit() call is ignored.

Here is a small code snippet on how to properly create a new bitmap image and set that as the source of an Image object.

// Define a BitmapImage.
Image myImage = new Image();
BitmapImage bi = new BitmapImage();

// Begin initialization.
bi.BeginInit();

// Set BitmapImage properties. (CacheOption,CreateOptions… etc.)

// End initialization.
bi.EndInit();


myImage.Source = bi;


Wednesday, February 13, 2013

How to Scroll to Selected Datagrid Item

If you programmatically select an item on a WPF datagrid, you may need to scroll to make sure that item is visible. One line of code will take care of that for you.

myGrid.ScrollIntoView(myGrid.SelectedItem);

That should do it.

Happy Coding!

Tuesday, February 5, 2013

The Basics: Intro to Windows Presentation Foundation

I have spoken to several developers this week who have heard of WPF, but have no experience with it. I have been working with this technology for so long, that I take it for granted. I decided to write a few blog posts specifically for those developers that are just starting out with WPF.
The Links First, here are a few useful links to get you started
http://www.microsoft.com/expression/
download Microsoft Expression Blend
http://www.microsoft.com/visualstudio/eng/products/visual-studio-overview 
go to express products to download the free version of Visual Studio
This is by far the Best book for learning WPF. I highly recommend it

Introduction Now that I've used the term WPF several times, I should probably give a formal definition for it. As seen in the title of this blog post, WPF stands for Windows Presentation Foundation. So why use WPF when there are other options like Windows Forms out there? While there are many opinions out there, I believe the biggest benefit to using WPF is that it provides a clear separation between the application behavior and the user interface. Rather than defining the user interface in code like VB or C#, WPF introduces xaml (eXtensible Application Markup Language). This xml markup is used to define the user interface. When an application is built, the compiler reads the xaml (pronounced zammel) markup and generates the appropriate objects to construct the user interface.
Everything you can do in xaml you can do in code. You can create a WPF application without writing a single line of xaml, but that is not common. Declaring your user interface in xaml provides a cleaner separation between the look of the application and the behavior of the application. It also allows you to use the design tools (like Expression Blend) available for creating complex user interfaces. Also, xaml is much easier to read and a lot shorter than code.
C# / Xaml Comparison
The following xaml and c# code both produce the same result – the following interface.
image
xaml
    <Grid>        
        <StackPanel>
            <Label Content="My First WPF App"/>
            <Button Content="Hello World"/>
            <TextBox/>            
        </StackPanel>
    </Grid>

C#
            Grid g = new Grid();
            StackPanel s = new StackPanel();

            Label l = new Label();
            l.Content = "My First WPF App";

            Button b = new Button();
            b.Content = "Hello World";

            TextBox t = new TextBox();

            //populate stack panel
            s.Children.Add(l);
            s.Children.Add(b);
            s.Children.Add(t);            

            //add stackpanel to grid
            g.Children.Add(s);

            //set application content
            this.Content = g;

From this small example you can clearly see that the C# code is much longer and more difficult to read than the equivalent xaml markup.

Xaml Basics

To initialize an object simply create a new xml element.

             <StackPanel/>
        <
Button
/>
        <
Label
/>
        <
TextBlock
/>
        <
TextBox
/>
        <
ListBox/>
 
         . . .
   
There are two ways of adding properties to elements:

1)Inline
             <StackPanel Orientation="Horizontal" Margin="2"/>   
        <
Button Content="Click Me" Height="50" Width
="100"/>
        <
Label Content
="Hi"/>
        <
TextBox Text
="Enter text here"/>
        <
ListBox Height="300"/>


or

2) As nested elements. This allows building more complex elements.
        <Button Height="50" Width="100">
            <StackPanel Orientation="Horizontal">
                <Label Content="Click"/>
                <Image Source="click_here.png"/>
            </StackPanel>
        </Button>


The Visual Tree
WPF introduces the notion of a visual tree and a logical tree. It is important to understand the difference between the two.

When building a user interface, one can talk about the different elements that make up the interface. That is what is referred to as the logical tree.

    <Grid>
        <Button/>
    </Grid>

The logical tree for this code is represented as
image

The visual tree refers to the various visual elements that make up a logical element. The logical tree just for the button above is represented as:

image

This specifies, in great detail, how the button control is visually constructed. WPF gives developers the flexibility to completely redefine visual tree of any given control. This is done via Styles and Templates.

Styles and Templates
Here is where WPF development, in my opinion, really shines. Styles can be used to make reusable chunks of code that define visual properties of specific UI elements or a certain type of element. They are very similar to Cascading Style Sheets in web development. With styles, you can easily define the look for all the buttons within a given application as a single style and apply it globally.style

Below I define 4 styles for Label controls. The first is the default style for all labels within scope. If a label is created within the scope of this style and no style is defined, it will pick up the properties defined by this style. Default styles are created in WPF by simply creating a style without giving it a Key (style identifier).

                <Style TargetType="{x:Type Label}">
                    <Style.Setters>
                        <Setter Property="Foreground" Value="Red"/>
                        <Setter Property="FontWeight" Value="Bold"/>
                        <Setter Property="FontSize" Value="40"/>
                    </Style.Setters>
                </Style>

                <Style TargetType="{x:Type Label}" x:Key="BigBlueStyle">
                    <Style.Setters>
                        <Setter Property="Foreground" Value="Blue"/>
                        <Setter Property="FontWeight" Value="Bold"/>
                        <Setter Property="FontSize" Value="40"/>
                    </Style.Setters>
                </Style>

                <Style TargetType="{x:Type Label}" x:Key="LittleGreenStyle">
                    <Style.Setters>
                        <Setter Property="Foreground" Value="Green"/>
                        <Setter Property="FontWeight" Value="Bold"/>
                        <Setter Property="FontSize" Value="10"/>
                    </Style.Setters>
                </Style>


The second and third styles both have Keys. In order to use this style, the label must set the Style attribute using the following syntax.

        <StackPanel>
            <Label Content="First Label"/>
            <Label Content="Second Label" Style="{DynamicResource BigBlueStyle}"/>
            <Label Content="Third Label" Style="{DynamicResource LittleGreenStyle}"/>
            <Label Content="Fourth Label" Foreground="Purple"/>
        </StackPanel>

The product of this code looks like this:

image

Notice how the fourth label overrides the foreground color to purple.

Templates are a bit different from styles. While styles allow you to set properties, templates allow you to redefine the visual tree of an element. There are two different kinds of templates used in WPF

1)Datatemplate – Used for describing how data should be displayed. This type of template is commonly used in list-based controls like listboxes or comboboxes.

2)ControlTemplate – Used for describing the appearance of a control.

Simple example:

In this example I change the visual tree of the button. This defines the button to be made up of a green grid with an inner stackpanel that has a textblock, a rectangle and a combobox. Note, the user can still interact with any of the elements inside the button like the combobox. This, in my opinion, is the single most powerful feature in WPF. Developers are completely free to redefine visual elements in inumerable ways to meet their needs.

       <Button Height="100" Width="200">
            <Button.Template>
                <ControlTemplate>
                    <Grid Background="Green">
                        <StackPanel  VerticalAlignment="Center"> 
                            <TextBlock Text="Click Me"/>
                            <Rectangle Fill="Black" Height="30" />
                            <ComboBox>
                                <ComboBox.Items>
                                    <ComboBoxItem Content="Item One"/>
                                    <ComboBoxItem Content="Item Two"/>
                                    <ComboBoxItem Content="Item Three"/>
                                </ComboBox.Items>
                            </ComboBox>
                        </StackPanel>                        
                    </Grid>
                </ControlTemplate>
            </Button.Template>
        </Button>
imageimage

This has only been a quick intro to WPF. I hope it’s been helpful to understand the basics of this technology. Please take a look around this blog to find other articles related to wpf development.

Happy Coding!

Friday, February 1, 2013

C# Basics: Switch Statement

The switch statement is a form of selection statement that executes some logic based on the value of a given parameter. Its purpose is to replace multiple conditional statements with a single switch statement.

Basic Syntax
switch (expression)
{
       case constant1:
             statement1;
             break;
       case constant2:
             statement2;
             break;
       case constant3:
             statement3;
             break;
       default:
             default statement;
             break;
 }
If the expression’s value does not match any of the constant values in the switch statement, the control flow is transferred to the statement following the default keyword.

The switch statement above can also be written with multiple if statements as follows:

if (expression1)
{
     statement1;
}
else if (expression2)
{
      statement2;
}
else if (expression3)
{
     statement3;
}
else
{
     default statement;
}

Case fall-through
all case statements within a switch statement must have a reachable endpoint. This is typically the break statement. However, any statement that will jump the execution out of the switch statement will also work. These are statements like return and throw. The only exception to this reachable endpoint rule is when there are no statements between case statements.

In the following example, statement 1 is executed if expression is equal to constant1 or constant2.

switch (expression)
{
     case constant1:                    
     case constant2:
            statement1;
            break;
     case constant3:
            statement3;
            break;  
     default:
            default statement;
            break;
}

Thursday, January 3, 2013

How to Detect a Touch Screen (C#)

Just a quick note to show you how to detect a touch screen. This code could be used to hide the application cursor if the application is running on a touch screen device.

I hope it helps.

private bool HasTouchInput()
{
return Tablet.TabletDevices.OfType<TabletDevice>().Any(t => t.Type == TabletDeviceType.Touch);
}


Friday, August 24, 2012

How to Change Application FontFamily at Runtime

This one stumped me for a while. There are a lot of blog posts out there on how to change the font family of a particular style if you know the key, or how to do it for all textblocks in the application. The problem I was facing was that I used a lot of Labels and other controls that did not pick up these changes. Not only that, but I found no way of editing my default styles at runtime. After trying several approaches, I came up with this solution. I don’t know if it will work for everyone, but in my case, it is working beautifully. I hope it helps.


        private void applyFontFamilySettings()
        {
            foreach (DictionaryEntry entry in Application.Current.Resources)
            {
                if (entry.Value is Style)
                {
                    Style originalStyle = (Style)entry.Value;
                    swapStyles(originalStyle, entry.Key, originalStyle.TargetType);
                }
            }
        }

        private void swapStyles(Style s, object styleKey, Type t)
        {
            Style newStyle = new System.Windows.Style()
            {
                TargetType = t
            };

            foreach (Setter st in s.Setters)
            {
                newStyle.Setters.Add(st);
            }

            newStyle.Setters.Add(new Setter(FontFamilyProperty, UiSettings.FontFamily));
            Application.Current.Resources[styleKey] = newStyle;
        }




Friday, August 5, 2011

Launching the Default Email Client

I was asked to write some code to send an email through the default email client and I was pleasantly surprised as to how easy it was to do. I had never done this before, so it was a learning experience for me, so I thought I’d share it with all of you.

string toEmail = "from@email.com";
string subject = "Test Subject";
string body = "test email message text";
string message =
string.Format("mailto:{0}?subject={1}&body={2}",toEmail, subject, body);
Process.Start(message);

So that should do it. It’s pretty simple. When you run this code, you should see the default email client launch with the appropriate fields filled in.

Cheers!