Tower
Tower

Reputation: 102785

Bindings not working in WPF window user control

I have this User Control XAML:

<Window x:Class="MyProj.Dialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell"
        mc:Ignorable="d">

    <Grid>
        <ItemsControl ItemsSource="{Binding Foos}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="ASd" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>

</Window>

and the corresponding code behind:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Effects;
using System.Windows.Threading;

namespace MyProj
{
    public partial class Dialog : Window
    {
        public Dialog() : base()
        {
            InitializeComponent();

            //DataContext = this;
        }

        public ObservableCollection<string> Foos = new ObservableCollection<string> { "foo", "bar" };
    }
}

The problem I'm having is that for some reason the ItemsControl does not display anything. The odd thing is that I don't even get binding warnings in the output.

Upvotes: 0

Views: 205

Answers (2)

Douglas
Douglas

Reputation: 54887

In WPF, the Path component of a binding can only refer to properties (or property paths), not fields. Try encapsulating your collection in a property:

private ObservableCollection<string> foos = 
    new ObservableCollection<string> { "foo", "bar" };

public ObservableCollection<string> Foos
{
    get { return foos; }
}

Also, you need to uncomment the line where you set the DataContext:

DataContext = this;

Upvotes: 5

J...
J...

Reputation: 31403

You can also bind fields (easiest if you name the component, but you need to reference it somehow) :

<ItemsControl ItemsSource="{Binding}" Name="myItems">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

with

private ObservableCollection<string> Foos = 
  new ObservableCollection<string> { "foo", "bar" };

public Dialog() : base
{
    InitializeComponent();
    myItems.DataContext = Foos;
}

This can be more flexible than hard-coding the binding in the XAML since you are not binding to a specific property of your class but rather to any object which exposes the correct properties. Supposing you had a number of collections, you could easily display any of them in the ItemsControl simply by changing (programmatically) its DataContext to whatever collection you wished to display.

Upvotes: 3

Related Questions