Nikolas Jíša
Nikolas Jíša

Reputation: 709

WPF ItemsSource internal collection

I have a UserControl with an ObservableCollection property. This property is supposed to be used for binding, however I don't want it to be visible outside of the assembly in order to satisfy the basic rules of OOP. Here is a demonstrating example which works, but when I change the access modifier of Data to internal it doesn't work anymore:

XAML:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" x:Name="Root">
    <ListBox ItemsSource="{Binding Data, ElementName=Root}"/>
</Window>

And code behind:

using System;
using System.Windows;
using System.Collections.ObjectModel;

namespace WpfApplication3
{
    public partial class MainWindow : Window
    {
        private readonly ObservableCollection<string> _data = new ObservableCollection<string>();
        public ObservableCollection<string> Data
        {
            get { return _data; }
        }

        public MainWindow()
        {
            InitializeComponent();
            Data.Add("XXX");
            Data.Add("YYY");
            new System.Threading.Thread(() =>
            {
                for (int i = 0; i < 3; i++)
                {
                    Dispatcher.Invoke(new Action(() => Data.Add("ZZZ " + i)));
                    System.Threading.Thread.Sleep(1000);
                }
            }).Start();
        }
    }
}

What would be the best way to achieve this?

Thanks for any efforts.

Upvotes: 0

Views: 760

Answers (2)

Monkey Shen
Monkey Shen

Reputation: 199

Try to set ItemSource in MainWindow constructor

XAML:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" x:Name="Root">
    <ListBox Name="listbox"/>
</Window>

And Code behind

using System;
using System.Windows;
using System.Collections.ObjectModel;

namespace WpfApplication3
{
    public partial class MainWindow : Window
    {
        private readonly ObservableCollection<string> _data = new ObservableCollection<string>();
        internal ObservableCollection<string> Data
        {
            get { return _data; }
        }

        public MainWindow()
        {
            InitializeComponent();

            listbox.ItemSource = this.Data;
            Data.Add("XXX");
            Data.Add("YYY");
            new System.Threading.Thread(() =>
            {
                for (int i = 0; i < 3; i++)
                {
                    Dispatcher.Invoke(new Action(() => Data.Add("ZZZ " + i)));
                    System.Threading.Thread.Sleep(1000);
                }
            }).Start();
        }
    }
}

Upvotes: 2

madbrendon
madbrendon

Reputation: 650

DataBinding in WPF works only with public properties.

MSDN

The properties you use as binding source properties for a binding must be public properties of your class. Explicitly defined interface properties cannot be accessed for binding purposes, nor can protected, private, internal, or virtual properties that have no base implementation

Upvotes: 0

Related Questions