Reputation: 439
I hope this question isnt to dumb, I've tried to search for a solution for 5hours, and mostly found helpfull stuff on this site, but I can not manage to fix my problem.
I have my Item Class with just this property:
public string ItemName { get; set; }
And a Class to hold Items:
public class ShoppingListItems
{
public static List<Item> ItemCollection { get; set; }
public ShoppingListItems()
{
ItemCollection = new List<Item>();
AddAnItem("test");
}
public static void AddAnItem(string name)
{
ItemCollection.Add(new Item()
{
ItemName = name
});
}
}
And in my XAML file, binding related code is:
xmlns:application="clr-namespace:ShoppingListTest"
<Grid.Resources>
<application:ShoppingListItems x:Key="ShoppingListItems" />
</Grid.Resources>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" DataContext="{StaticResource ShoppingListItems}">
<ListBox x:Name="listBox1" Height="Auto" ItemsSource="{Binding ItemCollection, Mode=TwoWay}">
<TextBlock x:Name="textBlock1" Text="{Binding ItemName}" FontSize="50" />
And then in my MainPage.xaml.cs, in a method on KeyDown I have:
ShoppingListItems.AddAnItem(textBox1.Text);
The list works great, and shows "test" in the listBox, but adding to the list does not work, I have tried to look at some NotifyPropertyChanged stuff, without any luck.
Any idea on what I need to do to update the listBox? I would be soooo glad if anyone had some tips that would make this work!
Upvotes: 1
Views: 3363
Reputation: 750
First I would recommend not using static members, it just seems to work better without.
Minor changes to ShoppingListItems:
public class ShoppingListItems
{
public ObservableCollection<Item> ItemCollection { get; set; }
public ShoppingListItems()
{
ItemCollection = new ObservableCollection<Item>();
AddAnItem("test");
AddAnItem("test2");
AddAnItem("test3");
}
public void AddAnItem(string name)
{
ItemCollection.Add(new Item()
{
ItemName = name
});
}
}
Things are non-static, and List<> is ObservableCollection<> instead.
In the xaml:
<Grid>
<Grid.Resources>
<DataTemplate x:Key="itemLayout" DataType="{x:Type local:Item}">
<TextBlock Text="{Binding ItemName}" FontSize="50" />
</DataTemplate>
</Grid.Resources>
<ListBox x:Name="itemsListBox" Margin="2" ItemsSource="{Binding}"
ItemTemplate="{DynamicResource itemLayout}"
IsSynchronizedWithCurrentItem="True">
</ListBox>
</Grid>
In the code-behind (the .cs file that corresponds to the xaml file):
private ShoppingListItems _shoppingList;
public MainWindow()
{
InitializeComponent();
_shoppingList = new ShoppingListItems();
itemsListBox.DataContext = _shoppingList.ItemCollection;
}
EDIT:
What I did was put the data template up in the grid resources, while you put the data template as part of the list box resources. As far as I can tell the only real difference is if the template is part of the grid resources it could be used in multiple places. Say you wanted two shopping lists, maybe one for things you need and another for things you've already bought, and you wanted them formatted the same way, it would be best to put the template up in the grid so both lists could reference it. Since you only have one list it probably doesn't matter, either way is fine.
As for the Singleton pattern, see: Singleton on Wikipedia
The simplest approach would have your ShoppingListItems look like this:
public class ShoppingListItems
{
private static ShoppingListItems _instance = new ShoppingListItems();
public ObservableCollection<Item> ItemCollection { get; private set; }
public static ShoppingListItems Instance { get { return _instance; } }
private ShoppingListItems()
{
ItemCollection = new ObservableCollection<Item>();
AddAnItem("test");
AddAnItem("test2");
AddAnItem("test3");
}
public void AddAnItem(string name)
{
ItemCollection.Add(new Item()
{
ItemName = name
});
}
}
Upvotes: 2
Reputation: 439
Thak you so much Zik, you code changes worked. In my XAML code I only changed to to ItemSource="{Binding}".
I really dont understand your last comment tho. Need to do some google search to try to understand, everthing I do is almost new for me :)
My XAML code for the list of items is like this now:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" DataContext="{StaticResource ShoppingListItems}">
<ListBox x:Name="listBox1" Height="Auto" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="5" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock1" Text="{Binding ItemName}" FontSize="50" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
And on the main grid I have this:
<Grid.Resources>
<application:ShoppingListItems x:Key="ShoppingListItems" />
</Grid.Resources>
This seems to work great. But if it is better, what should I change to add your code like:
<DataTemplate x:Key="itemLayout" DataType="{x:Type local:Item}">
and
ItemTemplate="{DynamicResource itemLayout}"
IsSynchronizedWithCurrentItem="True"
Upvotes: 0
Reputation: 905
Have you tried changing ItemCollection to be an ObservableCollection instead of a List?
Upvotes: 1