Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF binding multiple controls to different datacontexts

I have a scenario where I don't really know how to bind data to controls hosted in a UserControl to multiple datacontexts.

The data i want to bind comes from 2 classes

UserInfo, UserExtendedInfo 

The datacontext of the UserControl is set to UserInfo so i can bind most controls easily doing the following

<Label Name="LblEmail" Text="{Binding Email}" /> 

However I don't know how to bind properties from the UserExtendedInfo class easily. My initial thought was to set the datacontext of each control that want's to use the data from UserExtendedInfo so i could do the same. But this seems cumbersome as i would have to manually assign each one indivdually. The data for UserExtendedInfo must be fetched from the database each time the UserControl becomes visible so that it doesn't get out of sync.

XAML:

<Label Name="LblTest" Text="{Binding Locale}" /> 

Code Behind:

Private Sub UserManager_IsVisibleChanged(ByVal sender As System.Object, ByVal e As System.Windows.DependencyPropertyChangedEventArgs)           If DirectCast(e.NewValue, Boolean) Then             Dim user As UserInfo = DirectCast(DataContext, UserInfo)              If user IsNot Nothing Then                 Dim usrExt As UserExtenedInfo = UserController.GetUserExtended(user.userID)                  LblTest.DataContext = usrExt             Else                 Throw New ArgumentException("UserId doesn't exist or is less than 1")             End If         End If     End Sub 
like image 677
Alex Avatar asked Mar 25 '09 01:03

Alex


2 Answers

I would maybe think about wrapping your user object in a seperate class then setting the DataContext properties of sub-panels that contain the data.

For example:

public class UserDataContext {   public UserInfo UserInfo { get; set; }   public UserExtendedInfo UserExtendedInfo { get; set; } } 

Then in your UserControl.xaml:

<!-- Binding for the UserControl should be set in its parent, but for clarity --> <UserControl DataContext="{Binding UserDataContext}">   <StackPanel>     <Grid DataContext="{Binding UserInfo}">        <TextBlock Text="{Binding Email}" />     </Grid>     <Grid DataContext="{Binding UserExtendedInfo}">        <TextBlock Text="{Binding Locale}" />        <TextBlock Text="{Binding AboutMe}" />     </Grid>   </StackPanel> </UserControl> 

This assumes that your UserInfo class has a property of Email

and

That your UserExtendedInfo class has a property of Locale and AboutMe

like image 145
bendewey Avatar answered Sep 24 '22 16:09

bendewey


Here is the simplest method of all, and it works very well.

In the code-behind where you set the context, simply use an anonymous type containing all the desired values:

DataContext = new {   info = FetchUserInfoFromDatabase(),   extendedInfo = FetchExtendedUserInfoFromDatabase(), }; 

In the XAML you can bind to anything:

<UserControl>   <StackPanel>     <TextBlock Text="{Binding info.Email}" />     <TextBlock Text="{Binding extendedInfo.Locale} />   ... 

Alternatively you can bind in two levels as other answers have described:

<UserControl>   <StackPanel>     <Grid DataContext="{Binding info}">       <TextBlock Text={Binding Email}">       ... 
like image 41
Ray Burns Avatar answered Sep 24 '22 16:09

Ray Burns