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 : Setting the DataContext

3/22/2011 4:32:46 PM

FrameworkElement defines a property named DataContext that you can set to pretty much any object (in code) or generally a binding (in XAML). The DataContext is one of those properties that propagates down through the visual tree, at which point it can be combined with more local bindings. At the very least, the DataContext gives you a way to simplify individual bindings by eliminating repetition. In the broader view, DataContext is how you associate data with visual trees.

In this particular example, you can set the DataContext property on any element that is an ancestor to the TextBlock elements. Let’s set it on the most immediate ancestor, which is the StackPanel:

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

Now the StackPanel has its DataContext set to a Binding element that references just the source of the binding—the Clock resource. All the children of that StackPanel don’t need to reference that Source. It’s merged in with the bindings on the individual TextBlock elements.

You can set the DataContext to a Binding object as I’ve done:

DataContext="{Binding Source={StaticResource clock}}"

Or in this case you can set the DataContext directly to the source:

DataContext="{StaticResource clock}"

Either is acceptable and you’ll see both in my examples.

Once the Source property is removed from the individual Binding extensions, what begins to look more natural to me is for the “Path=” part of the individual bindings to be removed:

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

Remember that the “Path=” part of the Binding markup extension can be removed only if the Path is the first item. Each of the bindings now seems to reference a particular property of the DataContext:

<TextBlock Text="{Binding Hour}" />

Here’s the resultant display:



The DataContext is extremely useful when a page or a control is devoted to displaying the properties of a particular class. The DataContext can be set by code to switch between various instances of that class.

Although certainly not as common, you can also use DataContext with ElementName bindings. Here’s the visual tree from the BorderText.xaml file you saw earlier:

<Border Background="{Binding ElementName=this, Path=Background}"
BorderBrush="{Binding ElementName=this, Path=BorderBrush}"
BorderThickness="{Binding ElementName=this, Path=BorderThickness}"
CornerRadius="{Binding ElementName=this, Path=CornerRadius}"
Padding="{Binding ElementName=this, Path=Padding}">

<TextBlock Text="{Binding ElementName=this, Path=Text}"
TextAlignment="{Binding ElementName=this, Path=TextAlignment}"
TextDecorations="{Binding ElementName=this, Path=TextDecorations}"
TextWrapping="{Binding ElementName=this, Path=TextWrapping}" />
</Border>


You can instead set the DataContext on the Border to a Binding with the ElementName, and then the remaining bindings are simplified considerably:

<Border DataContext="{Binding ElementName=this}"
Background="{Binding Background}"
BorderBrush="{Binding BorderBrush}"
BorderThickness="{Binding BorderThickness}"
CornerRadius="{Binding CornerRadius}"
Padding="{Binding Padding}">

<TextBlock Text="{Binding Path=Text}"
TextAlignment="{Binding Path=TextAlignment}"
TextDecorations="{Binding Path=TextDecorations}"
TextWrapping="{Binding ElementName=this, Path=TextWrapping}" />
</Border>


Back to Clock: You may have noticed that I got a little lazy when coding the class and didn’t define properties for the various components of the date, such as Month and Year. Instead, I simply defined a property named Date of type DateTime. The OnTimerTick handler assigns to that property the static property DateTime.Today, which is a DateTime object with the time set to midnight. That means that this Date property is not firing off PropertyChanged events every tenth second. It’s only firing one at startup and then at the stroke of every midnight.

You can reference the individual properties of the Date property like this:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock Text="It's day number " />
<TextBlock Text="{Binding Source={StaticResource clock},
Path=Date.Day}" />
<TextBlock Text=" of month " />
<TextBlock Text="{Binding Source={StaticResource clock},
Path=Date.Month}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text=" of the year " />
<TextBlock Text="{Binding Source={StaticResource clock},
Path=Date.Year}" />
<TextBlock Text=", a " />
<TextBlock Text="{Binding Source={StaticResource clock},
Path=Date.DayOfWeek}" />
< TextBlock Text="." />
</StackPanel>
</StackPanel>
</Grid>


Or, you can set a DataContext on the StackPanel as before and eliminate the “Path=” part of the bindings:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel DataContext="{StaticResource clock}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock Text="It's day number " />
<TextBlock Text="{Binding Date.Day}" />
<TextBlock Text=" of month " />
<TextBlock Text="{Binding Date.Month}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text=" of the year " />
<TextBlock Text="{Binding Date.Year}" />
<TextBlock Text=", a " />
<TextBlock Text="{Binding Date.DayOfWeek}" />
<TextBlock Text="." />
</StackPanel>
</StackPanel>
</Grid>

Either version displays two lines of text:



Date is a property of Clock of type DateTime, and Day, Month, Year, and DayOfWeek are all properties of DateTime. There is no formatting here beyond that provided by default calls to ToString. The Day, Month, and Year properties are displayed as numbers. The DayOfWeek property is of a member of the DayOfWeektext, such as Wednesday, but the text won’t be localized. The DayOfWeek member names are in English so that’s what’s displayed. enumeration, so you’ll see actual

You can also set a DataContext that references both the Source and the Date property, so the individual bindings just reference properties of DateTime:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel DataContext="{Binding Source={StaticResource clock},
Path=Date}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock Text="It's day number " />
<TextBlock Text="{Binding Day}" />
<TextBlock Text=" of month " />
<TextBlock Text="{Binding Month}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text=" of the year " />
<TextBlock Text="{Binding Year}" />
<TextBlock Text=", a " />
<TextBlock Text="{Binding DayOfWeek}" />
<TextBlock Text="." />
</StackPanel>
</StackPanel>
</Grid>

Of course, there are lots of formatting options for dates documented with the DateTimeFormatInfo class in the System.Globalization namespace, so you can also make use of StringFormatConverter.

Suppose you want to include the name of the current month deep within a paragraph displayed using TextBlock. To use TextBlock to display a paragraph of text, you’ll want to set the TextWrapping property to Wrap. But now you can’t use StackPanel to concatenate multiple TextBlock elements. You need to include all the text in that single TextBlock, including the name of the month. How do you do it?

You will consider yourself a genius when you remember the Run class. The Run class has a Text property, so it seems like an ideal way to embed the month name (or some other binding) in a longer paragraph:

<!-- This will not work! -->
<TextBlock TextWrapping="Wrap">
This represents some long text that needs to display a month name of
<Run Text="{Binding Source={StaticResource clock},
Path=Date,
Converter={StaticResource stringFormat},
ConverterParameter='{0:MMMM}'}" />
and then continue with the rest of the paragraph.
</TextBlock>

This is exactly what you want, and the only problem is that it won’t work! It won’t work because the Text property of Run is not backed by a dependency property, and targets of data bindings must always be dependency properties.

It seems unfair that Run has this little problem, but frameworks are much like life, and life is not always fair.

Currently, you cannot do this little task entirely in XAML. You’ll need to give the Run a name and assign the Text property from code.

Other -----------------
- Data Bindings : A Simple Binding Server
- 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
 
 
Top 10 video Game
-   Heroes Reborn | The Extraordinary Among Us (Preview)
-   Battleborn | E3 2015 Gameplay Demo
-   Fortnite [PC] Mac Showcase Trailer
-   Overwatch [PC] Zarya Gameplay Trailer
-   Tony Hawk's Pro Skater 5 [PS3/PS4/X360/XOne] THPS Is Back Trailer
-   Bombing Busters Trailer
-   Blade & Soul 'What is Blade & Soul?' Trailer
-   Cast of the Seven Godsends 'Plague Armour' Trailer
-   Guncraft X360 Trailer
-   Disgaea 5: Alliance of Vengeance | Official Trailer
-   XCOM 2 [PC] E3 2015 Gameplay Trailer
-   RONIN | Turn-Based Action Platformer
-   Balance Benny | Trailer
-   We Happy Few | An Uncle Jack Episode - Nighty Night, The Pied Piper of Hamlyn, Part1
-   Beyond Good & Evil 2 | Teaser Trailer
Popular tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 windows Phone 7 windows Phone 8
programming4us programming4us
 
Popular keywords
HOW TO Swimlane in Visio Visio sort key Pen and Touch Creating groups in Windows Server Raid in Windows Server Exchange 2010 maintenance Exchange server mail enabled groups Debugging Tools Collaborating
programming4us programming4us
PS4 game trailer XBox One game trailer
WiiU game trailer 3ds game trailer
Trailer game
 
programming4us
Heroes Charge
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Game Trailer