Hallo Everyone,
I am trying to data bind an object data source to a ListBox in WPF. But I am
having a problem populating the object.
I would like to populate the DataProvider object inside this button click
private void button1_Click(object sender, RoutedEventArgs e)
{
// THIS DOES NOT WORK
DataProvider d;
d = (DataProvider)GetValue(DataProviderProperty);
City Bern = new City("Bern");
d.Citys.Add(Bern);
SetValue(DataProviderProperty, d);
}
Any ideas?
Nigel...
This is what I have
Windows1.xaml
=============
<Window x:Class="WpfLists.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:y="clr-namespace:WpfLists"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.DataContext>
<y

ataProvider />
</Grid.DataContext>
<ListBox Margin="45,28,113,81" Name="listBox1" ItemsSource="{Binding
Citys}"/>
<Button Height="23" HorizontalAlignment="Right" Margin="0,0,28,23"
Name="button1" VerticalAlignment="Bottom" Width="75"
Click="button1_Click">Button</Button>
</Grid>
</Window>
Windows1.xaml.cs
================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfLists
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
public static readonly DependencyProperty DataProviderProperty =
DependencyProperty.Register("DataProvider", typeof(DataProvider),
typeof(Window1));
private void button1_Click(object sender, RoutedEventArgs e)
{
// THIS DOES NOT WORK
DataProvider d;
d = (DataProvider)GetValue(DataProviderProperty);
City Bern = new City("Bern");
d.Citys.Add(Bern);
SetValue(DataProviderProperty, d);
}
}
}
DataPriver.cs
=============
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace WpfLists
{
public class DataProvider : BindableObject
{
//THIS CAUSES AN ERROR
//public DataProvider()
//{
// this.MyCountry = new Country("Switzerland");
//}
private Country _MyCountry;
public Country MyCountry
{
get { return _MyCountry; }
set
{
if (value == _MyCountry)
return;
_MyCountry = value;
base.RaisePropertyChanged("Country");
}
}
//private List<City> _citys = new List<City>();
public IList<City> Citys
{
get { return _MyCountry.Citys; }
}
}
}
BindableObject.cs
=================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
namespace WpfLists
{
/// <summary>
/// Implements the INotifyPropertyChanged interface and
/// exposes a RaisePropertyChanged method for derived
/// classes to raise the PropertyChange event. The event
/// arguments created by this class are cached to prevent
/// managed heap fragmentation.
/// </summary>
[Serializable]
public abstract class BindableObject : INotifyPropertyChanged
{
#region Data
private static readonly Dictionary<string, PropertyChangedEventArgs>
eventArgCache;
private const string ERROR_MSG = "{0} is not a public property of {1}";
#endregion // Data
#region Constructors
static BindableObject()
{
eventArgCache = new Dictionary<string, PropertyChangedEventArgs>();
}
protected BindableObject()
{
}
#endregion // Constructors
#region Public Members
/// <summary>
/// Raised when a public property of this object is set.
/// </summary>
[field:NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Returns an instance of PropertyChangedEventArgs for
/// the specified property name.
/// </summary>
/// <param name="propertyName">
/// The name of the property to create event args for.
/// </param>
public static PropertyChangedEventArgs
GetPropertyChangedEventArgs(string propertyName)
{
if (String.IsNullOrEmpty(propertyName))
throw new ArgumentException(
"propertyName cannot be null or empty.");
PropertyChangedEventArgs args;
// Get the event args from the cache, creating them
// and adding to the cache if necessary.
lock (typeof(BindableObject))
{
bool isCached = eventArgCache.ContainsKey(propertyName);
if (!isCached)
{
eventArgCache.Add(
propertyName,
new PropertyChangedEventArgs(propertyName));
}
args = eventArgCache[propertyName];
}
return args;
}
#endregion // Public Members
#region Protected Members
/// <summary>
/// Derived classes can override this method to
/// execute logic after a property is set. The
/// base implementation does nothing.
/// </summary>
/// <param name="propertyName">
/// The property which was changed.
/// </param>
protected virtual void AfterPropertyChanged(string propertyName)
{
}
/// <summary>
/// Attempts to raise the PropertyChanged event, and
/// invokes the virtual AfterPropertyChanged method,
/// regardless of whether the event was raised or not.
/// </summary>
/// <param name="propertyName">
/// The property which was changed.
/// </param>
protected void RaisePropertyChanged(string propertyName)
{
this.VerifyProperty(propertyName);
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
// Get the cached event args.
PropertyChangedEventArgs args =
GetPropertyChangedEventArgs(propertyName);
// Raise the PropertyChanged event.
handler(this, args);
}
this.AfterPropertyChanged(propertyName);
}
#endregion // Protected Members
#region Private Helpers
[Conditional("DEBUG")]
private void VerifyProperty(string propertyName)
{
Type type = this.GetType();
// Look for a public property with the specified name.
PropertyInfo propInfo = type.GetProperty(propertyName);
if (propInfo == null)
{
// The property could not be found,
// so alert the developer of the problem.
string msg = string.Format(
ERROR_MSG,
propertyName,
type.FullName);
Debug.Fail(msg);
}
}
#endregion // Private Helpers
}
}