Hudlommen Hudlommen - 1 month ago 20
C# Question

ObservableCollection vs INotifyCollectionChanged in UWP with MVVM

So im stood in a situation, where i have a main XML file with data. That data file i then convert into a List so i can access the data in my program.

So for now i can get that data showed, but i dont know how to filter it and get that filteret version shown.

So lets say i have a list of recipes. Now i want to see all the recipes with lettuce in. How do i go about that?

I understand that i need a MVVM setup, and i have that, but its static, given that i right now only have one list created when the view is made. So if i hard code i only want to see lettuce, i can do that, but how do i go about making a button for that? Or even better a search box?
Iv'e tried to look into ObservableCollections or INotifyCollectionChanged, but i am unsure what will actually lead to what i need.

What would be the best approach?

Thank you in advance.

So i found out a solution to my problem.

XML:

<?xml version="1.0" encoding="UTF-8"?>
<List>
<Person>
<Number>1</Number>
<FirstName>Frank</FirstName>
<LastName>Heist</LastName>
</Person>
<Person>
<Number>1</Number>
<FirstName>James</FirstName>
<LastName>Calder</LastName>
</Person>
<Person>
<Number>1</Number>
<FirstName>Jane</FirstName>
<LastName>Calder</LastName>
</Person>

</List>


Models > Data.cs

public class dataRaw
{
public string data { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
}

public class collectionGenerator
{
public static List<dataRaw> getList()
{
var doc = XDocument.Load("Data.xml");
var dataList = doc.Root
.Descendants("Person")
.Select(node => new dataRaw
{
data = node.Element("Number").Value,
firstName = node.Element("FirstName").Value,
lastName = node.Element("LastName").Value,
})
.ToList();
return dataList;
}
}


xaml.cs

public sealed partial class MainPage : Page
{
public List<dataRaw> t1;
public List<dataRaw> t3;
public ObservableCollection<dataRaw> t2;
public MainPage()
{
this.InitializeComponent();

t1 = collectionGenerator.getList();
t2 = new ObservableCollection<dataRaw>(t1);
}

private void Filter_Click(object sender, RoutedEventArgs e)
{
t1 = collectionGenerator.getList();
t2.Clear();
string data = TB1.Text;

if(data != "")
{
var Vtest = from VT in t1
where VT.firstName == data || VT.lastName == data
select VT;
foreach (var VT in Vtest)
{
t2.Add(new dataRaw { data = "1", firstName = VT.firstName, lastName = VT.lastName });

}
}
else
{
var Vtest = from VT in t1
where VT.data == "1"
select VT;
foreach (var VT in Vtest)
{
t2.Add(new dataRaw { data = "1", firstName = VT.firstName, lastName = VT.lastName });

}
}
}
}


xaml

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="200" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<GridView ItemsSource="{x:Bind t2}" Grid.Row="1">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:dataRaw">
<StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<TextBlock Width="200" FontSize="48" Text="{x:Bind firstName}" Margin="0,0,20,0" Grid.Row="0"/>
<TextBlock Width="200" FontSize="48" Text="{x:Bind lastName}" Margin="0,0,20,0" Grid.Row="1"/>

</Grid>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>

<Button Content="Filter" Name="Filter" FontSize="36" Click="Filter_Click" Width="200" Height="100" Grid.Row="2" />
<TextBox Name="TB1" Height="100" Width="400" Grid.Row="2" />

</Grid>

Answer

You need an observable collection here as you want to bind view's listview,for example, to a collection in viewmodel. To be able to change the view depending on search filter, you can pass a searchString parameter from a textbox in view to view model. In the passed string filter property, filter the collection as well using Linq or other means. And as this collection in viewmodel is bound to View's List, it will update the view when the collection is changed (that is the functionality of observablecollection).

Comments