I've been struggling for a while on this. I'm a bit of a newbie, but i lurked a lot and still couldn't find a solution to my problem, so I decided to post my question here.
I'm binding a pivot to a collection of objects I want to display to create a gallery. Here is my pivot control bound to a list called gallery, where each object contains 2 strings (url and description).
<controls:Pivot ItemsSource="{Binding gallery}" Grid.Row="0" x:Name="galleryPivot">
<controls:Pivot.ItemTemplate>
<DataTemplate>
<StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Source="{Binding url}" />
<Grid Visibility="{Binding ElementName=galleryPivot, Path=DataContext.ShowDetail}">
<ListBox>
<ListBoxItem>
<StackPanel>
<TextBlock Text="{Binding description}" />
</StackPanel>
</ListBoxItem>
</ListBox>
</Grid>
</Grid>
</StackPanel>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
The datacontext is the viewmodel and initialized in the constructor of the page. Here is my ViewModel:
public class GalleryViewModel : INotifyPropertyChanged
{
public List<Gallery> gallery
{
get { return Globals.pictures; }
}
private Visibility _showDetail = Visibility.Collapsed;
public Visibility ShowDetail
{
get { return _showDetail; }
set {
_showDetail = value;
RaisePropertyChanged("ShowDetail");
}
}
public GalleryViewModel()
{ }
public event PropertyChangedEventHandler PropertyChanged = delegate { return; };
protected void RaisePropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
The gallery object is a list in my ViewModel, as the ShowDetail property. As ShowDetail is outside the scope, I tried to set ElementName as explained here.
The pivot binds well to the gallery list, but when I change the value of ShowDetail, the grid won't hide. I also tried to set ElementName to LayoutRoot but it still won't work.
My question, how can I bind the visibility when it is outside the scope of the itemtemplate?
Within a
DataTemplate
the ElementName binding refers only to the names of elements that are within thatDataTemplate
. The data context within your data template is theGallery
instance, not theGalleryViewModel
. You could move the ShowDetail property down to theGallery
class instead.If you'd rather not do that, then an alternative would be to use a proxy for the data context, which you add as a resource to the page and bind to the page's data context (a
GalleryViewModel
instance presumably). You can then reference that resource as you would any other resource to get at the parent data context.If you're not familiar with this proxy concept, then Dan Wahlin's post on the subject should help.