TheQuestioner
TheQuestioner

Reputation: 447

Metro XAML Binding inside ListView

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

Answers (2)

har07
har07

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

Rob J
Rob J

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:

http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.data.binding.relativesource.aspx

The doc does not mention the Ancestor feature, so I'm not sure if that is available in the WinRT libraries.

Upvotes: 0

Related Questions