2

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>();
    }
}
13
  • Whats the purpose of the nested ListView? It seems like the ItemsSource="{Binding nodes}" part makes no sense. Commented Nov 26, 2012 at 17:20
  • The nested list view will be to show a collection of Rows. So you have a collection of rows, which in turn has a collection of Nodes. Commented Nov 26, 2012 at 17:21
  • Can you post the code for class Row here? Commented Nov 26, 2012 at 17:38
  • 2
    It compiles if you define Row class as: ` public class Row : ObservableCollection<Node> { }` Commented Nov 26, 2012 at 17:50
  • 2
    @EthanShafer - Nested ListView is of no use. OuterListView ItemsSource will be ObservableCollection of Nodes (i.e. instance of a Row) and for inner ListView itemsSource will be nodes property exposed in class 'Row` whose count is 0. Hence no item is shown. Commented Nov 26, 2012 at 17:59

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.