Reputation: 263
I am trying to bind my object list to a listbox.
Here is the object list definition:
class LoadFactory : INotifyCollectionChanged
{
public ObservableCollection<Load> Loads = new ObservableCollection<Load>();
public LoadFactory()
{
AddLoad(new Load(15));
AddLoad(new Load(12));
AddLoad(new Load(25));
}
public int LoadCount()
{
return Loads.Count();
}
public void AddLoad(Load load)
{
Loads.Add(load);
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(new NotifyCollectionChangedAction()));
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
public ObservableCollection<Load> GetLoads()
{
return new ObservableCollection<Load>(Loads);
}
}
public class Load
{
public static int LoadCount=0;
public int Index = 0;
public Load(float LoadMagnitude)
{
magnitude = LoadMagnitude;
Index = LoadCount;
LoadCount++;
}
private float magnitude;
public float Magnitude
{
get
{
return magnitude;
}
set
{
magnitude = value;
}
}
public float ToFloat()
{
return magnitude;
}
public override string ToString()
{
return magnitude.ToString() + " ft";
}
}
And here is my XAML:
<Window x:Class="Sunny3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Sunny3"
Title="MainWindow" Height="500" Width="1000">
<Grid>
<Grid Name="motherGrid">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="1" Click="Button_Click_1">Hello</Button>
<ListBox Grid.Row="2" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="3"></Setter>
<Setter Property="FontSize" Value="20"></Setter>
<Setter Property="Width" Value="70"></Setter>
<Setter Property="Foreground" Value="Blue"></Setter>
</Style>
</DataTemplate.Resources>
<StackPanel>
<Grid>
<TextBox Text="{Binding Path=.}"></TextBox>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
And my code behind:
public partial class MainWindow : Window
{
LoadFactory LF;
public MainWindow()
{
LF = new LoadFactory();
InitializeComponent();
this.DataContext = LF.Loads;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Load newone = new Load(154);
LF.AddLoad(newone);
}
}
The problem is that the I cannot seem to get my loads bound to the text boxes.
Any suggestions?
Upvotes: 0
Views: 844
Reputation: 4563
You need to make Loads a property, not a field.
public ObservableCollection<Load> Loads { get; set; }
public LoadFactory()
{
Loads = new ObservableCollection<Load>();
AddLoad(new Load(15));
AddLoad(new Load(12));
AddLoad(new Load(25));
}
The text box binding should be to a property within the load class.
<TextBox Text="{Binding Path=Magnitude}"></TextBox>
Upvotes: 2
Reputation: 7038
First, have you tried to test it without modifying the ListBox ItemTemplate?
Lets take a look on your DataContexts. In your MainWindow constructor, you have a LoadsFactory instance, but you set the "Loads" property as the Window.DataContext, instead of the instance itself. Then in the ListBox you bind the ItemsSource to it's current DataContext. This way, the Listbox.ItemsSource is bound to an ObservableCollection. Fine.
As your LF seems to be your main ViewModel, wouldn't make more sense to set it as the MainWindow.DataContext and then bind the ListBox.ItemsSource to the Loads property?
What was the point on implementing INotifyCollectionChanged to the LF if you are not going to bind to it? In addition, I believe that just implementing INotifyCollectionChanged on an object doesn't make it elegible for being used as item source. It has, in first place, to implement IEnumerable or some other collection variant (IEnumerable, IList, etc).
Upvotes: 0
Reputation: 117
You could try to bind directly to the observable collection
<ListBox Grid.Row="2" ItemsSource="{Binding Loads}">
Upvotes: 0