The button click does not fire if I use the DelegateCommand from Prism. If I write a command class for button click and not use Prism, then it works. This is my code with Prism:
This is my View XAML:
<Window x:Class="MVVMPractice2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label Content="Customer Name" HorizontalAlignment="Left" Margin="0,0,0,292.8"></Label>
<Label Name="lblName" HorizontalAlignment="Left" Margin="108,0,0,292.8" Width="37" Content="{Binding TxtCustomerName}"></Label>
<Label Content="Sales Amount" HorizontalAlignment="Left" Margin="0,28,0,264.8"></Label>
<TextBox Name="lblAmount" HorizontalAlignment="Left" Margin="101,28,0,264.8" Width="44" Text="{Binding TxtAmount}"></TextBox>
<Label Content="Buying Habits" HorizontalAlignment="Left" Margin="0,56,0,236.8"></Label>
<Label Name="lblBuyingHabits" HorizontalAlignment="Left" Margin="108,56,0,236.8" Width="52" Background="{Binding LblAmountColor}"></Label>
<Label Content="Married" HorizontalAlignment="Left" Margin="0,84,0,208.8" Width="62"></Label>
<CheckBox Name="chkMarried" HorizontalAlignment="Left" Margin="102,84,0,208.8" IsChecked="{Binding IsMarried}"></CheckBox>
<Label Content="Tax" HorizontalAlignment="Left" Margin="0,112,0,180.8"></Label>
<TextBlock Name="lblTax" HorizontalAlignment="Left" Margin="108,117,0,175.8" Width="37" Text="{Binding TaxAmount}"></TextBlock>
<Button Name="btnTax" Content="Calculate Tax" Margin="118,158,287.4,123.8" Command="{Binding UpdateCommand}"></Button>
</Grid>
</Window>
And the ViewModel:
public class MainWindowViewModel : BindableBase
{
//instantiate the model
private Customer customer = new Customer();
//property for button click command
private DelegateCommand UpdateCommand;
//constructor to instantiate the buttons click command
public MainWindowViewModel()
{
UpdateCommand = new DelegateCommand(customer.CalculateTax, customer.IsValid);
}
//this property maps customer name from model to the view
public string TxtCustomerName
{
get { return customer.CustomerName; }
set { customer.CustomerName = value; }
}
//this property maps amount from model to the view
public string TxtAmount
{
get { return Convert.ToString(customer.Amount); }
set { customer.Amount = Convert.ToDouble(value); }
}
//this property maps and transforms color from model to the view
public string LblAmountColor
{
get
{
if (customer.Amount > 2000)
{
return "Blue";
}
else if (customer.Amount > 1500)
{
return "Red";
}
return "Yellow";
}
}
//this property maps and transforms married from model to the view
public bool IsMarried
{
get
{
if (customer.Married == "Married")
{
return true;
}
else if (customer.Married == "UnMarried")
{
return false;
}
return false;
}
set
{
if (value)
{
customer.Married = "Married";
}
else
{
customer.Married = "UnMarried";
}
}
}
//this property maps tax from model to the view
public string TaxAmount
{
get { return Convert.ToString(customer.Tax); }
set { customer.Tax = Convert.ToDouble(value); }
}
}
and the Model:
public class Customer
{
//model property
private string customerName = "Ivan";
public string CustomerName
{
get { return customerName; }
set { customerName = value; }
}
//model property
private double amount = 2000;
public double Amount
{
get { return amount; }
set { amount = value; }
}
//model property
private string married = "Married";
public string Married
{
get { return married; }
set { married = value; }
}
//model property
private double tax;
public double Tax
{
get { return tax; }
set { tax = value; }
}
//this modifier calculates the tax
public void CalculateTax()
{
if (amount > 2000)
{
tax = 20;
}
else if (amount > 1000)
{
tax = 10;
}
else
{
tax = 5;
}
}
//this modifier validates the amount
public bool IsValid()
{
if (amount < 0)
{
return false;
}
else
{
return true;
}
}
}
As pointed to in the comment above, changing the field to a property helps, and firing NotifyPropertyChanged (removed irrelevant parts):
public class MainWindowViewModel : BindableBase
{
//property for button click command
public DelegateCommand UpdateCommand { get; }
//constructor to instantiate the buttons click command
public MainWindowViewModel()
{
UpdateCommand = new DelegateCommand(() => {
customer.CalculateTax();
OnPropertyChanged( () => TaxAmount );
}, customer.IsValid);
}
//this property maps tax from model to the view
public string TaxAmount
{
get { return Convert.ToString(customer.Tax); }
set { customer.Tax = Convert.ToDouble(value); }
}
}
Alternatively, make Customer implement INotifyPropertyChanged and use something like PropertyObserver to pass the events to the view.
Related
I struggle to refresh the data attached to the RADdatagrid. The view with the Datagrid shows the position of a team in a competition. Every time a new game is finished the view has to be updated automatically. The data is stored in a sqlite database and a simple sql query gets the positions from the database. A button in the view that calls the query method does the job but I want to update the grid directly after the finished game is stored. I implemented INotifyPropertyChanged but no result. I also tried to fire the button_click event but that also didn't bring me the result. I want to do this right but I am open to a quick and dirty solution. Here is a bit of my code:
<StackPanel Grid.Row="2" Orientation="Horizontal">
<TextBlock Grid.Row="2" Margin="40,0,0,5">Team Ranking</TextBlock>
<Button x:Name="RefreshViewButton" Command="{Binding Path=RefreshView}" Margin="40 0 0 0 " Click="RefreshViewButton_Click">Refresh</Button>
</StackPanel>
<StackPanel Grid.Row="6" Margin="0, 0, 50, 0" VerticalAlignment="Stretch">
<telerikGrid:RadDataGrid
AutoGenerateColumns="False"
x:Name="Datagrid"
BorderThickness="0"
ItemsSource="{x:Bind ViewModel.TeamResult, Mode=TwoWay}"
ColumnDataOperationsMode="Flyout"
GridLinesVisibility="None"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
UserEditMode="None" >
<telerikGrid:RadDataGrid.Columns>
<telerikGrid:DataGridNumericalColumn PropertyName="Rank" Header="Rank" SizeMode="Auto"/>
<telerikGrid:DataGridTextColumn PropertyName="Team_Naam" Header="TeamNaam" SizeMode="Auto"/>
<telerikGrid:DataGridTextColumn PropertyName="WedstrijdPunten" Header="WP" CanUserEdit="False" CanUserFilter="False" CanUserGroup="False" CanUserReorder="False" CanUserResize="False" CanUserSort="False" SizeMode="Auto" />
<telerikGrid:DataGridTextColumn PropertyName="PuntenVoor" Header="GP" SizeMode="Auto"/>
</telerikGrid:RadDataGrid.Columns>
</telerikGrid:RadDataGrid>
</StackPanel>
This is my view:
public sealed partial class TeamTotals : Page
{
public TeamResultsViewModel ViewModel { get; set; } = new TeamResultsViewModel();
public TeamTotals()
{
DataContext = ViewModel;
this.InitializeComponent();
}
public void RefreshViewButton_Click(object sender, RoutedEventArgs e)
{
ViewModel.LoadTeamResultsData();
}
}
My ViewModel:
public class TeamResultsViewModel : TeamModel
{
//public List<TeamModel> TeamResult = new List<TeamModel>();
public ObservableCollection<TeamModel> TeamResult = new ObservableCollection<TeamModel>();
TeamModel tm = new TeamModel();
public TeamResultsViewModel()
{
LoadTeamResultsData();
tm.PropertyChanged += Tm_PropertyChanged;
}
private void Tm_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
public void LoadTeamResultsData()
{
int i = 0;
if(TeamResult != null)
{
TeamResult.Clear();
}
try
{
string sql = "Select Team_Naam, WedstrijdPunten, PuntenVoor, PuntenTegen FROM Team WHERE KlasseId = 1 " +
"ORDER BY WedstrijdPunten DESC, PuntenVoor DESC LIMIT 10;";
var resultaat = SqliteDataAccess.LoadData<TeamModel>(sql, new Dictionary<string, object>());
foreach (var x in resultaat)
{
TeamResult.Add(x);
x.Rank = i++;
}
}
catch (Exception ex)
{
var messagedialog2 = new MessageDialog($"{ex}");
_ = messagedialog2.ShowAsync();
}
return;
}
}
and the model:
public class TeamModel : INotifyPropertyChanged
{
private int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
private int _klasseId;
public int KlasseId
{
get { return _klasseId; }
set { _klasseId = value; }
}
private string _team_naam;
public string Team_Naam
{
get { return _team_naam; }
set { _team_naam = value; }
}
private int _coachId;
public int CoachId
{
get { return _coachId; }
set { _coachId = value; }
}
private int _clubId;
public int ClubId
{
get { return _clubId; }
set { _clubId = value; }
}
private int _puntenVoor;
public int PuntenVoor
{
get { return _puntenVoor; }
set { _puntenVoor = value; }
}
private int _puntenTegen;
public int PuntenTegen
{
get { return _puntenTegen; }
set { _puntenTegen = value; }
}
private int _wedstrijdPunten;
public int WedstrijdPunten
{
get { return _wedstrijdPunten; }
set
{
_wedstrijdPunten = value;
OnPropertyChanged("WedstrijdPunten");
}
}
private int _rank;
public int Rank
{
get { return _rank; }
set { _rank = value; }
}
public List<SpelerModel> TeamLeden { get; set; } = new List<SpelerModel>();
public string Standen => $"{Team_Naam} : {PuntenVoor}";
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public override string ToString()
{
return Standen;
}
}
I am creating an application with an MVVM model, in one of my views I have an ObservableCollection where by means of a button I create a new element and it appears on the screen, the problem is that I have a button to update that changes the name of the ListViewItem , and this name doesn't change until I switch between views
Problem
The DNP3-Master are my Items and the button I activate changes the name to "Test" but it is not updated until I change my view (this is a UserControl)
MasterViwModel
class MasterViewModel : ObservableObject
{
public ushort count { get; set; }
public ObservableCollection<MasterTraceModel> MasterReference { get; set; }
public RelayCommand CreateMaster { get; set; }
public RelayCommand Update { get; set; }
private ObservableCollection<MasterModel> _masterList;
public ObservableCollection<MasterModel> MasterList
{
get { return _masterList; }
set { _masterList = value; OnPropertyChanged(); }
}
private MasterModel _selectedMaster;//SelectedItem from ListView
public MasterModel SelectedMaster
{
get { return _selectedMaster; }
set { _selectedMaster = value; OnPropertyChanged(); }
}
public MasterViewModel()
{
MasterList = new ObservableCollection<MasterModel>();//my Observable Collections
//Stuff
this.count = 1;
//Stuff
CreateMaster = new RelayCommand(o =>
{
MasterList.Add(new MasterModel(this.count, "127.0.0.1", "20000", runtime));
this.count = (ushort)(count + 1);
});//Here I add the elements to my ObservableCollections
//Stuff
Update = new RelayCommand(o =>
{
SelectedMaster.SetName("Test");
});
}
}
MasterView
<UserControl x:Class="Prototype.MVVM.View.MasterView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:viewmodel="clr-namespace:Prototype.MVVM.ViewModel"
d:DataContext="{d:DesignInstance Type=viewmodel:MasterViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Border Margin="20,20,0,20" Background="#151515" CornerRadius="8">
<ListView Name="MasterListView" Margin="5"
ItemsSource="{Binding MasterList}"
SelectedItem="{Binding SelectedMaster}"
ItemContainerStyle="{StaticResource MasterTheme}"
Background="Transparent"
BorderThickness="0"
/>
</Border>
<StackPanel Grid.Column="1" Margin="0,20,0,0">
<Button Margin="0,0,0,10" Grid.Column="1" Style="{StaticResource SmallBtn}" Command="{Binding Update}">
<Image Height="24" Width="24" Source="/Icons/cil-reload.png" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
</Button>
</StackPanel>
</Grid>
</UserControl>
MasterModel
class MasterModel : ObservableObject
{
public string Name { get; set; }
public ushort Adress { get; set; }
public string Host { get; set; }
public string Port { get; set; }
public Runtime _runtime { get; set; }
public MasterChannel channel { get; set; }
public ConnectStrategy CStrategy { get; set; }
public string[] Delay { get; set; }
public MasterModel(ushort Adress, string Host, string Port, Runtime runtime)
{
this.Name = "DNP3-Master-" + Adress.ToString();
this.Adress = Adress;
this.Host = Host;
this.Port = Port;
this._runtime = runtime;
CStrategy = new ConnectStrategy();
//CStrategy.MinConnectDelay = new TimeSp
Delay = new string[3];
Delay[0] = CStrategy.MinConnectDelay.ToString();
Delay[1] = CStrategy.MaxConnectDelay.ToString();
Delay[2] = CStrategy.ReconnectDelay.ToString();
this.channel = MasterChannel.CreateTcpChannel(//Stuff);
}
public void SetName(string name)
{
this.Name = name;
}
public void Star(Runtime runtime)
{
Task.Run(async () =>
{
try
{
await MasterFunctions.RunChannel(channel);
}
finally
{
runtime.Shutdown();
}
});
}
The MasterModel class should implement the INotifyPropertyChanged event and raise the PropertyChanged event for the data-bound property when you call SetName:
private string _name;
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged(); }
}
Using an ObservableCollection<T> doesn't replace the need to implement INotifyPropertyChanged and raise change notifications for the individual items in the collection. It notifies the view when items are added to and removed from the collection only.
I am working on the ability to add and delete rows in an observable collection.
Since the original post I have created a test app that only has the ability to delete rows from the observable collection. I populate the database externally then open it in this just to test the delete function which doesn't work. It executes the RemoveAt line, deletes from the Observable Collection but the view does not update. Here is all my code:
Model:
public class TestModel : ObservableObject
{
#region Properties
private Double id;
public Double ID
{
get { return id; }
set
{
id = value;
RaisePropertyChangedEvent("ID");
}
}
private string type;
public string Type
{
get { return type; }
set
{
type = value;
RaisePropertyChangedEvent("Type");
}
}
private decimal amount;
public decimal Amount
{
get { return amount; }
set
{
amount = value;
RaisePropertyChangedEvent("Amount");
}
}
private string notes;
public string Notes
{
get { return notes; }
set
{
notes = value;
RaisePropertyChangedEvent("Notes");
}
}
#endregion
}
Viewmodel:
public class MainWindowViewModel : ObservableObject
{
#region GetData
public MainWindowViewModel()
{
Transactions = DatabaseFunctions.getTransactionData();
}
#endregion
#region ObservableCollections
private ObservableCollection<TestModel> transactions;
public ObservableCollection<TestModel> Transactions
{
get { return transactions; }
set
{
transactions = value;
RaisePropertyChangedEvent("Transactions");
}
}
#endregion
#region Properties
public static string SharedWith;
private Double id;
public Double ID
{
get { return id; }
set
{
id = value;
RaisePropertyChangedEvent("ID");
}
}
private string type;
public string Type
{
get { return type; }
set
{
type = value;
RaisePropertyChangedEvent("Type");
}
}
private decimal amount;
public decimal Amount
{
get { return amount; }
set
{
amount = value;
RaisePropertyChangedEvent("Amount");
}
}
private string notes;
public string Notes
{
get { return notes; }
set
{
notes = value;
RaisePropertyChangedEvent("Notes");
}
}
#endregion
public void DeleteTransactionRow(List<TestModel> SelectedTransaction, int SelectedIndex)
{
Transactions.RemoveAt(SelectedIndex);
}
View:
<Window x:Class="OCTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:Properties="clr-namespace:OCTest.Properties"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid"
Title="Test" SizeToContent="WidthAndHeight"
xmlns:ViewModel="clr-namespace:OCTest.ViewModel">
<Window.DataContext>
<ViewModel:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<xcdg:DataGridControl x:Name="TransactionsDataGrid" Grid.Row="0" ItemsSource="{Binding Transactions, Mode=TwoWay}" AutoCreateColumns="False" SelectionMode="Single">
<xcdg:DataGridControl.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete Row" Click="DeleteTransactionRow_Click"/>
</ContextMenu>
</xcdg:DataGridControl.ContextMenu>
<xcdg:DataGridControl.Columns>
<xcdg:Column Title="Type" FieldName="Type" ReadOnly="True"/>
<xcdg:Column Title="Amount" FieldName="Amount">
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding StringFormat={}{0:C}}"/>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
</xcdg:Column>
<xcdg:Column Title="Notes" FieldName="Notes"/>
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
</Grid>
Code behind that deals with the delete command and passes needed information to the view model:
public partial class MainWindow : Window
{
MainWindowViewModel mainwindowviewmodel = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
}
private void DeleteTransactionRow_Click(object sender, RoutedEventArgs e)
{
List<TestModel> selectedtransaction = TransactionsDataGrid.SelectedItems.Cast<TestModel>().ToList();
mainwindowviewmodel.DeleteTransactionRow(selectedtransaction, TransactionsDataGrid.SelectedIndex);
}
private void MouseRightButtonUpHandler(object sender, RoutedEventArgs e)
{
this.TransactionsDataGrid.SelectedItem = ((DataCell)sender).ParentRow.DataContext;
}
}
So hopefully someone can see why the RemoveAt doesn't update the view.
You need to set the DataContext of the MainWindow to your view model:
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
I'd also recommend looking into binding click events to commands in your view model rather than relying on the code behind.
I have a viewmodel named AllUserViewModel that contains a list of UserViewModels.
The UserViewModel is binded with a UserControl.
This is my MainWindow, foreach user I add a UserControl to a stackpanel container.
public partial class MainWindow : Window
{
public AllUserViewModel allUserViewModel { get; set; }
public MainWindow()
{
InitializeComponent();
DwmDropShadow.DropShadowToWindow(this);
allUserViewModel = new AllUserViewModel();
this.DataContext = allUserViewModel;
allUserViewModel.Users.Add(new UserViewModel(new User(1, "Robby", "Bezet")));
allUserViewModel.Users.Add(new UserViewModel(new User(2, "Erwin", "Bezet")));
allUserViewModel.Users.Add(new UserViewModel(new User(3, "Kevin", "Bezet")));
foreach (UserViewModel u in allUserViewModel.Users)
{
Container.Children.Add(new UserControlButton(u));
}
Container.MouseEnter += new MouseEventHandler(Container_MouseEnter);
}
void Container_MouseEnter(object sender, MouseEventArgs e)
{
UserViewModel u = allUserViewModel.GetUser(2);
u.Name = "Laurens"; // Doesn't work
}
}
To each UserControlButton I pass a UserViewModel
public partial class UserControlButton : UserControl
{
public UserViewModel userViewModel { get; set; }
public UserControlButton(UserViewModel u)
{
this.InitializeComponent();
this.DataContext = u;
}
}
And this is my UserControlButton
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:ee="http://schemas.microsoft.com/expression/2010/effects"
mc:Ignorable="d"
x:Class="UserControlSolution.UserControlButton"
x:Name="UserControl"
Height="50" Background="#FF2F2F2F"
VerticalAlignment = "Top"
Margin="2,0,0,5"
>
<StackPanel x:Name="UserContainer" Orientation="Vertical" VerticalAlignment="Center" Grid.Column="1" Background="{DynamicResource DarkGrey}">
<TextBlock x:Name="NameLabel" FontSize="16" Foreground="#FFE5E5E5" Text="{Binding Name}" VerticalAlignment="Top" FontFamily="Segoe UI Semibold" RenderTransformOrigin="0.5,0.5" Margin="0,0,0,2"/>
<TextBlock x:Name="UserStatusLabel" Text="{Binding UserStatus}" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFE5E5E5" />
</StackPanel>
</UserControl>
AllUserViewmodel
public class AllUserViewModel : BaseViewModel
{
ObservableCollection<UserViewModel> _users;
public AllUserViewModel()
{
Users = new ObservableCollection<UserViewModel>();
}
/// <summary>
/// Observable Collection of Users
/// Uses INotifyPropertyChange when list changes
/// </summary>
public ObservableCollection<UserViewModel> Users
{
get { return _users; }
set
{
if (_users != value)
{
_users = value;
NotifyPropertyChanged("Users");
}
}
}
public void AddUser(User user)
{
UserViewModel userViewModel = new UserViewModel(user);
Users.Add(userViewModel);
}
public UserViewModel GetUser(int ID)
{
foreach (UserViewModel u in Users)
{
if(u.ID == ID)
return u;
}
return null;
}
}
And UserViewModel
public class UserViewModel : BaseViewModel
{
readonly User _user;
public UserViewModel(User user)
{
if (user == null)
throw new ArgumentNullException("User");
_user = user;
}
public string Name
{
get { return _user.Name; }
set
{
if (value == _user.Name)
return;
_user.Name = value;
NotifyPropertyChanged("UserName");
}
}
public string UserStatus
{
get { return _user.UserStatus; }
set
{
if (value == _user.UserStatus)
return;
_user.UserStatus = value;
NotifyPropertyChanged("UserStatus");
}
}
public int ID
{
get { return _user.ID; }
}
}
The problem is that the 3 users are shown initially, but when I try to change the name on the mouse enter event, the name is not changed although the NotifyPropertyChanged was triggered.
public string Name
{
get { return _user.Name; }
set
{
if (value == _user.Name)
return;
_user.Name = value;
NotifyPropertyChanged("UserName");
}
}
Your property is called Name but you raise a PropertyChanged event for a property called UserName !
I have a problem trying to bind my list to list view and I get an empty list view. I have tried changining my list to a property as I have seen this solve other peoples problem with no luck, any help appreciated.
Here is the XAML
<Window x:Class="key_stage_level_2_app.Window7"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Window7" Height="600" Width="800" Loaded="Window_Loaded">
<Grid>
<TabControl Height="536" HorizontalAlignment="Left" Name="tabControl1" VerticalAlignment="Top" Width="778">
<TabItem Header="Results2" Name="tabItem2">
<Grid>
<ListView Height="323" HorizontalAlignment="Left" Margin="107,96,0,0" Name="listView2" VerticalAlignment="Top" Width="186" ItemsSource="{Binding Path=someList}" >
<ListView.View>
<GridView>
<GridViewColumn Width="80" Header="Name" DisplayMemberBinding="{Binding Path=Name}"/>
<GridViewColumn Width="80 " Header="Result" DisplayMemberBinding="{Binding Path=Result}"/>
</GridView>
</ListView.View>
</ListView>
Here is the code behind
namespace key_stage_level_2_app
{
/// <summary>
/// Interaction logic for Window7.xaml
/// </summary>
public partial class Window7 : Window
{
App app = (App)App.Current;
private List<Pupil> someList { get; set; }
public Window7()
{
someList = new List<Pupil>();
foreach (Pupil pupil in app.PupilList)
{
someList.Add(pupil);
}
someList.Add(new Pupil
{
Name = "Simon",
Result = 100,
Grade = 100.00,
ExtensionWork = true,
TakenTest = true
});
Console.WriteLine("someList size = " + someList.Count);
InitializeComponent();
}
And the Class
class Pupil
{
public String name;
int result;
double grade;
bool extensionWork;
bool takenTest;
public Pupil(String Pname, int Presult, double Pgrade, bool PextensionWork, bool PtakenTest)
{
Name = Pname;
Result = Presult;
Grade = Pgrade;
ExtensionWork = PextensionWork;
TakenTest = PtakenTest;
}
public Pupil()
{
}
public String Name
{
get { return name; }
set { name = value; }
}
public int Result
{
get { return result; }
set { result = value; }
}
public double Grade
{
get { return grade; }
set { grade = value; }
}
public bool ExtensionWork
{
get { return extensionWork; }
set { extensionWork = value; }
}
public bool TakenTest
{
get { return takenTest; }
set { takenTest = value; }
}
Change your class access modifier to:
public class Pupil
and make the someList property public:
public List<Pupil> SomeList { get; set; }
So the view can actually see it.
You are getting nothing because you are creating new list but your list is empty, do this:
someList = new List<Pupil>();
someList.Add(new Pupil
{
Name = "Simon",
Result = 100,
Grade = 100.00,
ExtensionWork = true,
TakenTest = true
});
foreach (Pupil pupil in app.PupilList)
{
someList.Add(pupil);
}
After InitializeComponent(); add the following line:
DataContext = this;
so that the View knows where to get the someList from.
In addition, both Window7 and Pupil should implement the INotifyPropertyChanged interface to allow updating and avoid memory leaks.