Ethan Shafer
Ethan Shafer

Reputation: 68

WPF Data Binding not showing

So I'm having what should be a simple XAML Data Binding error. I've got the below XAML with two classes (so far) that they used for DataBinding, a Row, which contains an ObservableCollection rows. The nodes have a bunch of extra associated information and I'm trying to show these nodes in a grid-like fashion (it's going to be used for a path-finding algorithm.)

The problem is that the "Here" TextBlock doesn't show up. But I know that the Nodes are getting bound properly because their values show up in the Debugging StackPanel.

<Window.Resources>
    <local:Row x:Key="TestRow">
        <local:Node x="0" y="0" Cost="20" />
        <local:Node x="0" y="1" Cost="20" />
        <local:Node x="0" y="2" Cost="20" />
    </local:Row>
</Window.Resources>
<Grid Name="MainGrid" Margin="10,10,10,10" >
    <Grid.RowDefinitions>
        <RowDefinition Height="150" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <StackPanel Margin="0,25,0,0" 
                DataContext="{Binding ElementName=AStarListView, 
                                      Path=SelectedItem}" 
                x:Name="Debugging" Orientation="Vertical" >
        <TextBlock Text="{Binding x}" />
        <TextBlock Text="{Binding y}" />
        <TextBlock Text="{Binding Cost}" />
    </StackPanel>
    <ListView Grid.RowSpan="2" Margin="2,2,2,2" Grid.Column="1" 
              x:Name="AStarListView" 
              ItemsSource="{StaticResource TestRow}" >
        <ListView.ItemTemplate>
            <DataTemplate DataType="local:Row">
                <ListView ItemsSource="{Binding nodes}" Width="48" Height="48" >
                    <ListView.ItemTemplate>
                        <DataTemplate DataType="local:Node"> 
                            <TextBlock Text="Here" />
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

Here's the (stripped) Node class.

public class Node : INotifyPropertyChanged
{
    public Tuple<int, int> coordinates { get; set; }

    public int x
    {
        get
        {
            if (this.coordinates == null)
                return -1;
            return this.coordinates.Item1;
        }
        set
        {
            if (this.coordinates != null)
                this.coordinates = new Tuple<int, int>(value, y);
            else
                this.coordinates = new Tuple<int, int>(value, -1);

            OnPropertyChanged("x");
        }
    }
    public int y
    {
        get
        {
            if (this.coordinates == null)
                return -1;
            return this.coordinates.Item2;
        }
        set
        {
            if (this.coordinates != null)
                this.coordinates = new Tuple<int, int>(x, value);
            else
                this.coordinates = new Tuple<int, int>(-1, value);
            OnPropertyChanged("y");
        }
    }

    private Node _parent;

    private int _Cost;
    public int Cost
    {
        get
        {
            return _Cost;
        }
        set
        {
            _Cost = value;
            OnPropertyChanged("Cost");
        }
    }

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChangedEventArgs args = 
                 new PropertyChangedEventArgs(propertyName);
            this.PropertyChanged(this, args);
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

Here's the Row class:

public class Row : ObservableCollection<Node>
{
    public ObservableCollection<Node> nodes { get; set; }

    public Row()
    {
        this.nodes = new ObservableCollection<Node>();
    }
}

Upvotes: 2

Views: 2833

Answers (1)

Ethan Shafer
Ethan Shafer

Reputation: 68

Here's the corrected XAML, the class definitions are correct in the question, need to replace "AStarListView" with this XAML.

<ListView Grid.RowSpan="2" Margin="2,2,2,2" Grid.Column="1" x:Name="AStarListView" 
           ItemsSource="{StaticResource TestRow}" >

     <ListView.ItemTemplate>
         <DataTemplate DataType="local:Node">
             <Grid Background="#dddddd" >
                 <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding x}"/>
                 <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding y}"/>
                 <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding Cost}"/>
                 <Grid.RowDefinitions>
                     <RowDefinition Height="24"/>
                     <RowDefinition Height="24"/>
                 </Grid.RowDefinitions>
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition Width="24"/>
                     <ColumnDefinition Width="24"/>
                 </Grid.ColumnDefinitions>
             </Grid>
         </DataTemplate>
     </ListView.ItemTemplate>
 </ListView>

My problem was that I had the ListViews too deeply nested. The inner ListView was binding to the "nodes" property of a Node, which didn't exist.

Upvotes: 1

Related Questions