Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Phone

Data Bindings : A Simple Binding Server

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
3/22/2011 4:29:40 PM
I sometimes think of business objects that are intended to be referenced in XAML files through bindings as binding servers. They expose public properties and fire PropertyChanged events when these properties change.

For example, suppose you want to display the current time in a Windows Phone 7 application, and you want to be fairly flexible about what you display. Perhaps sometimes you only want to display seconds, and you want to do this entirely in XAML. For example, you might want a bit of XAML that says “The current seconds are …” followed by a number that changes every second. The technique I’ll show you here can be extended to many other types of applications beyond clocks, of course.

Although you’ll want to implement the visuals entirely in XAML, you’re going to need some code—perhaps a class named simply Clock that has properties named Year, Month, Day, DayOfWeek, Hour, Minute, and Second. We’ll instantiate this Clock class in a XAML file and access the properties through data bindings.

As you know, there already is a structure in .NET that has properties with the names Year, Month, Day, and so forth. It’s called DateTime. Although DateTime is essential for writing the Clock class, it’s not quite satisfactory for our purposes because the properties in DateTime don’t dynamically change. Each DateTime object represents a particular immutable date and time. In contrast, the Clock class I’ll show you has properties that change to reflect the current moment, and it will notify the external world about these changes through the PropertyChanged event

This Clock class is in the Petzold.Phone.Silverlight library. Here it is:

Example 1. Silverlight Project: Petzold.Phone.Silverlight File: Clock.cs
using System;
using System.ComponentModel;
using System.Windows.Threading;

namespace Petzold.Phone.Silverlight
{
public class Clock : INotifyPropertyChanged
{
int hour, min, sec;
DateTime date;

public event PropertyChangedEventHandler PropertyChanged;

public Clock()
{
OnTimerTick(null, null);

DispatcherTimer tmr = new DispatcherTimer();
tmr.Interval = TimeSpan.FromSeconds(0.1);
tmr.Tick += OnTimerTick;
tmr.Start();
}

public int Hour
{
protected set
{
if (value != hour)
{
hour = value;
OnPropertyChanged(new PropertyChangedEventArgs("Hour"));
}
}
get
{
return hour;
}
}

public int Minute
{
protected set
{
if (value != min)
{
min = value;
OnPropertyChanged(new PropertyChangedEventArgs("Minute"));
}
}
get
{
return min;
}
}

public int Second
{
protected set
{
if (value != sec)
{
sec = value;
OnPropertyChanged(new PropertyChangedEventArgs("Second"));
}
}
get
{
return sec;
}
}

public DateTime Date
{
protected set
{
if (value != date)
{
date = value;
OnPropertyChanged(new PropertyChangedEventArgs("Date"));
}
}
get
{
return date;
}
}

protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
{
if (PropertyChanged != null)
PropertyChanged(this, args);
}

void OnTimerTick(object sender, EventArgs args)
{
DateTime dt = DateTime.Now;
Hour = dt.Hour;
Minute = dt.Minute;
Second = dt.Second;
Date = DateTime.Today;
}
}
}


The Clock class implements INotifyPropertyChanged and therefore includes a public event named PropertyChanged. Near the bottom, a protected OnPropertyChanged method is also included and is responsible for firing the actual event. The constructor of the class installs a handler for the Tick event of the DispatcherTimer initialized to an interval of 1/10th second. The OnTimerTick handler (at the very bottom of the class) sets new values of the class’s Hour, Minute, Second, and Date properties, all of which are structured very similarly.

For example, look at the Hour property:

public int Hour
{
protected set
{
if (value != hour)
{
hour = value;
OnPropertyChanged(new PropertyChangedEventArgs("Hour"));
}
}
get
{
return hour;
}
}

The set accessor is protected. The value is only set internally and we don’t want external classes messing with it. The set accessor checks if the value being set to the property equals the value stored as a field; if not, it sets the hour field to the new value and calls OnPropertyChanged to fire the event.

Some programmers don’t include the if statement to check that the property is actually changing, with the result that the PropertyChanged event is fired whenever the property is set, even if it’s not changing. That’s not a good idea—particularly for a class like this. We really don’t want a PropertyChanged event reporting that the Hour property is changing every 1/10th second if it’s really changing only every hour.

To use the Clock class in a XAML file, you’ll need a reference to the Petzold.Phone.Silverlight library and an XML namespace declaration:

xmlns:petzold="clr-namespace:Petzold.Phone.Silverlight;assembly=Petzold.Phone.Silverlight"


When a binding source is not derived from DependencyObject, you don’t use ElementName In the Binding. Instead, you use Source. The bindings we want to create set Source to the Clock object in the Petzold.Phone.Silverlight library.

You can insert a reference to the Clock class directly in the element form of Binding:

<TextBlock>
<TextBlock.Text>
<Binding Path="Second">
<Binding.Source>
<petzold:Clock />
</Binding.Source>
</Binding>
</TextBlock.Text>
</TextBlock>

The Source property of Binding is broken out as a property element and set to an instance of the Clock class. The Path property indicates the Second property of Clock.

Or, more conventionally, you define the Clock as a XAML resource:

<phone:PhoneApplicationPage.Resources>
<petzold:Clock x:Key="clock" />
. . .
</phone:PhoneApplicationPage.Resources>

Then the Binding markup extension can reference that resource:

TextBlock Text="{Binding Source={StaticResource clock}, Path=Second}" />

Notice the embedded markup expression for StaticResource.

This approach is demonstrated in the TimeDisplay project, which uses a horizontal StackPanel to concatenate text:

Example 2. Silverlight Project: TimeDisplay File: MainPage.xaml
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock Text="The current seconds are " />
<TextBlock Text="{Binding Source={StaticResource clock},
Path=Second}" />
</StackPanel>
</Grid>

And here it is:



To re-emphasize: The binding target (the Text property of the TextBlock) must be a dependency property. That is required. To keep the target updated with changing values from the binding source (the Second property of Clock), the source should implement some kind of notification mechanism, which it does.

Of course, I don’t need the StackPanel with the multiple TextBlock elements. Using the StringFormatConverter (which I’ve included as a resource in TimeDisplay with a key of “stringFormat” so you can experiment with it) I can simply include the whole text like so:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding Source={StaticResource clock},
Path=Second,
Converter={StaticResource stringFormat},
ConverterParameter='The current seconds are {0}'}" />
</Grid>


Now the Binding markup expression has two embedded markup expressions.

If you want to display several properties of the Clock class, you’ll need to go back to using multiple TextBlock elements. For example, this will format the time with colons between the hours, minutes, and seconds and leading zeros for the minutes and seconds:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock Text="{Binding Source={StaticResource clock},
Path=Hour}" />
<TextBlock Text="{Binding Source={StaticResource clock},
Path=Minute,
Converter={StaticResource stringFormat},
ConverterParameter=':{0:D2}'}" />
<TextBlock Text="{Binding Source={StaticResource clock},
Path=Second,
Converter={StaticResource stringFormat},
ConverterParameter=':{0:D2}'}" />
</StackPanel>
</Grid>

As you can see, the three bindings all include the same Source setting. Is there some way that allows us to avoid the repetition? Yes there is, and the technique also illustrates an extremely important concept.

Other -----------------
- Data Bindings : Notification Mechanisms
- Data Bindings - The “this” Source
- Data Bindings - Relative Source
- Data Bindings - Binding Converters
- Data Bindings : Target and Mode
- Data Bindings : Source and Target
- Dependency Properties - Attached Properties
- Dependency Properties - Panels with Properties
- Dependency Properties - A New Type of Toggle
- Dependency Properties - Deriving from UserControl
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server