Reputation: 447
I'm using the next code to display a ListView. The ListView contains a TextBlock which has a FontSized bound to a variable on my MainPage :
<ListView x:Name="ListView"
SelectionMode="Single"
SelectionChanged="ListView_OnSelectionChanged"
Grid.Row="1"
Margin="8,16"
>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding DisplayName}"
FontSize="{Binding Path=FontSizeListViewTitle}" Margin="6,0,0,0" TextWrapping="NoWrap" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The problem is that FontSize="{Binding Path=FontSizeListViewTitle}" doesn't appear to work correctly. It shows me the text with a fontSize close to 6 (or something) despite the fact that the variable FontSizeListViewTitle only takes values between 16 and 24.
What's interesting is the fact that if I put the TextBlock outside the ListView, it works perfect. The problem only appears when I try to use the binding inside the ListView. Also, the Text="{Binding DisplayName} works perfectly and the TextBlock shows the text that it has to show.
Some code from the .cs file now :
private int _fontSizeListViewTitle;
public int FontSizeListViewTitle
{
get { return _fontSizeListViewTitle; }
set
{
_fontSizeListViewTitle = value;
OnPropertyChanged("FontSizeListViewTitle");
}
}
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
internal void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
public MainPage()
{
InitializeComponent();
this.DataContext = this;
ListView.ItemsSource = MyList; // MyList is an Observable Collection
}
Upvotes: 0
Views: 1100
Reputation: 89285
ListViewItem's DataContext is the object in your Observable Collection. You can see it when declaring TextBlock's Text binding in ListView's ItemTemplate as {Binding DisplayName}
instead of {Binding MyList.DisplayName}
or {Binding MyList[0].DisplayName}
or anything else. And FontSize="{Binding FontSizeListViewTitle}"
won't work because the object in Observable doesn't have FontSizeListViewTitle property.
The solution is to bind FontSize to ListView's DataContext where you put FontSizeListViewTitle property like following :
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding DisplayName}" Margin="6,0,0,0" TextWrapping="NoWrap"
FontSize="{Binding Path=DataContext.FontSizeListViewTile, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
UPDATE :
Since FindAncestor is missing in WinRT, the simplest work around is to use ElementName to find the ListView, then bind FontSize to ListView's DataContext.
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding DisplayName}" Margin="6,0,0,0" TextWrapping="NoWrap"
FontSize="{Binding ElementName=listView, Path=DataContext.FontSizeListViewTile}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Upvotes: 3
Reputation: 6629
The datatemplate is looking for the font size binding in the list view items source rather than the overall datacontext. You can use a relative source in the font size binding like so:
FontSize="{Binding Path=DataContext.FontSizeListViewTile, RelativeSource={RelativeSource TemplatedParent}}"
I'm not in front of my pc at the moment, so the syntax may be off slightly, but you get the idea. MS doc:
The doc does not mention the Ancestor feature, so I'm not sure if that is available in the WinRT libraries.
Upvotes: 0