Reputation: 83
I recently started to learn WPF and naturally I try to understand MVVM which from what I read is the normal way to program wpf applications.
I took a basic source from the internet for user management and started to build from there. Basically I have a listbox bind to a sql database through a ObservableCollection that display the username and when an item is selected all the details for that user are show in a datagrid.
In the window I also have a groupbox where you can add a new user to database and here lies the problem: the listox is not updated with the new user after I click the add button - I need to close and reopen the application for the new user to be shown in the listbox.
Where am I wrong?
My model class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Threading.Tasks;
namespace user_management.Model
{
public class Utilizatori:INotifyPropertyChanged
{
//public int id { get; set; }
private int _id;
public int id
{
get
{
return _id;
}
set
{
this._id = value;
OnPropertyChanged("id");
}
}
//public string nume { get; set; }
private string _nume;
public string nume
{
get
{
return _nume;
}
set
{
this._nume = value;
OnPropertyChanged("nume");
}
}
//public string parola { get; set; }
private string _parola;
public String parola
{
get
{
return _parola;
}
set
{
this._parola = value;
OnPropertyChanged("parola");
}
}
//public bool isadmin { get; set; }
private bool _isadmin;
public bool isadmin
{
get
{
return _isadmin;
}
set
{
this._isadmin = value;
OnPropertyChanged("isadmin");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
My viewModel:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Input;
using user_management.Model;
namespace user_management.ViewModel
{
public class UtilizatoriViewModel : INotifyPropertyChanged, IRequireViewIdentification
{
private Guid _viewId;
public Guid ViewID
{
get { return _viewId; }
}
static String connectionString = @"*****;";
SqlConnection con;
SqlCommand cmd;
SqlDataAdapter adapter;
SqlDataReader reader;
DataSet ds;
//public ObservableCollection<Utilizatori>utilizatori { get; set; }
private ObservableCollection<Utilizatori> _utilizatori;
public ObservableCollection<Utilizatori> utilizatori
{
get
{
return _utilizatori;
}
set
{
_utilizatori = value;
OnPropertyChanged("utilizatori");
}
}
public String txtSelectedItem { get; set; }
public UtilizatoriViewModel()
{
txtSelectedItem = "Va rugam sa alegeti un utilizator";
FillList();
_viewId = Guid.NewGuid();
}
public Utilizatori utiliz { get; set; }
private string userName;
public string UserName
{
get { return this.userName; }
set
{
this.userName = value;
this.OnPropertyChanged("UserName");
}
}
private string numeNou;
public string NumeNou
{
get { return this.numeNou; }
set
{
this.numeNou = value;
this.OnPropertyChanged("NumeNou");
}
}
private string parolaNou;
public string ParolaNou
{
get { return this.parolaNou; }
set
{
this.parolaNou = value;
this.OnPropertyChanged("ParolaNou");
}
}
private bool eadminNou;
public bool EadminNou
{
get { return this.eadminNou; }
set
{
if (eadminNou == value) return;
eadminNou = value;
this.OnPropertyChanged(EadminNou.ToString());
}
}
public string Password { private get; set; }
private ICommand _login;
public ICommand Login
{
get
{
if (_login == null)
{
_login = new RelayCommand(
param => Logare()
);
}
return _login;
}
}
//private bool CanSave()
//{
// return true;
//}
private ICommand _iesire;
public ICommand Iesire
{
get
{
if (_iesire == null)
{
_iesire = new RelayCommand(
param => IesireW()
);
}
return _iesire;
}
}
private ICommand _salveaza;
public ICommand Salveaza
{
get
{
if (_salveaza == null)
{
_salveaza = new RelayCommand(
param => AdaugaP()
);
}
return _salveaza;
}
}
private ICommand _salveazaModificari;
public ICommand SalveazaModificari
{
get
{
if (_salveazaModificari == null)
{
_salveazaModificari = new RelayCommand(
param => ModificaUser()
);
}
return _salveazaModificari;
}
}
private void Logare()
{
{
String message = "Login failed. please try again.";
try
{
con = new SqlConnection(connectionString);
con.Open();
cmd = new SqlCommand("Select * from dbo.Users where UsernAME=@UserName", con);
cmd.Parameters.AddWithValue("@UserName", UserName);
reader = cmd.ExecuteReader();
if (reader.Read())
{
if (reader["uSERpASS"].ToString().Equals(Password, StringComparison.InvariantCulture))
{
Utilizatori logati = new Utilizatori();
message = "1";
//logati.nume = txtUserId.Text.ToString();
logati.nume = reader["UsernAME"].ToString();
logati.parola = reader["uSERpASS"].ToString();
}
}
reader.Close();
reader.Dispose();
cmd.Dispose();
con.Close();
}
catch (Exception ex)
{
message = ex.Message.ToString();
}
if (message == "1")
{
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
WindowManager.CloseWindow(ViewID);
}
else
System.Windows.Forms.MessageBox.Show(message, "Info");
}
}
private void IesireW()
{
WindowManager.CloseWindow(ViewID);
}
private void FillList()
{
try
{
con = new SqlConnection(connectionString);
con.Open();
cmd = new SqlCommand("select * from dbo.Users", con);
adapter = new SqlDataAdapter(cmd);
ds = new DataSet();
adapter.Fill(ds, "dbo.Users");
if (utilizatori == null)
utilizatori = new ObservableCollection<Utilizatori>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
utilizatori.Add(new Utilizatori
{
id = Convert.ToInt32(dr[0].ToString()),
nume = dr[1].ToString(),
parola = dr[2].ToString(),
isadmin = bool.Parse(dr[3].ToString())
});
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
finally
{
ds = null;
adapter.Dispose();
con.Close();
con.Dispose();
}
}
private void AdaugaP()
{
try
{
con = new SqlConnection(connectionString);
con.Open();
cmd = new SqlCommand("INSERT INTO dbo.Users(UsernAME, uSERpASS, IsAdmin) VALUES(@Nume, @Parola, @Eadmin);", con);
SqlParameter numeNouP = new SqlParameter("@Nume", SqlDbType.NVarChar);
numeNouP.Value = this.NumeNou;
SqlParameter parolaNouP = new SqlParameter("@Parola", SqlDbType.NVarChar);
parolaNouP.Value = this.ParolaNou;
SqlParameter eadminP = new SqlParameter("@Eadmin", SqlDbType.Bit);
eadminP.Value = this.EadminNou;
cmd.Parameters.Add(numeNouP);
cmd.Parameters.Add(parolaNouP);
cmd.Parameters.Add(eadminP);
cmd.ExecuteScalar();
//reader.Close();
//reader.Dispose();
cmd.Dispose();
con.Close();
System.Windows.Forms.MessageBox.Show("Adaugarea s-a facut cu succes!");
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
private void ModificaUser()
{
try
{
con = new SqlConnection(connectionString);
con.Open();
cmd = new SqlCommand("UPDATE dbo.Users SET UsernAME=@Nume, uSERpASS=@Parola, IsAdmin=@Eadmin WHERE id=@Id", con);
SqlParameter numeNouP = new SqlParameter("@Nume", SqlDbType.NVarChar);
numeNouP.Value = utiliz.nume;
SqlParameter parolaNouP = new SqlParameter("@Parola", SqlDbType.NVarChar);
parolaNouP.Value = utiliz.parola;
SqlParameter eadminP = new SqlParameter("@Eadmin", SqlDbType.Bit);
eadminP.Value = utiliz.isadmin;
SqlParameter IDD = new SqlParameter("@Id", SqlDbType.Int, 11);
IDD.Value = utiliz.id;
cmd.Parameters.Add(numeNouP);
cmd.Parameters.Add(parolaNouP);
cmd.Parameters.Add(eadminP);
cmd.Parameters.Add(IDD);
cmd.ExecuteScalar();
//reader.Close();
//reader.Dispose();
cmd.Dispose();
con.Close();
System.Windows.Forms.MessageBox.Show("Modificarea s-a facut cu succes!");
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
public void SelectedItem(Utilizatori utilizator)
{
txtSelectedItem = "Ati selectat " + utilizator.nume + "(ID: " + utilizator.id + ", cu parola : " + utilizator.parola + " care este admin: "+ utilizator.isadmin+")";
OnPropertyChanged("txtSelectedItem");
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
public interface IRequireViewIdentification
{
Guid ViewID { get; }
}
My view:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;
using user_management.Model;
using user_management.ViewModel;
namespace user_management
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
UtilizatoriViewModel ut;
public MainWindow()
{
InitializeComponent();
ut = new UtilizatoriViewModel();
base.DataContext = ut;
}
private void lstBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var item = (ListBox)sender;
ut.SelectedItem((Utilizatori)item.SelectedItem);
}
}
}
My XAML:
<Window x:Class="user_management.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="#fff"
Title="WPF ListBox from MS SQL Database" Height="580.944" Width="736.949" WindowStyle="ThreeDBorderWindow" WindowStartupLocation="CenterScreen">
<StackPanel Orientation="Vertical">
<TextBlock Text="WPF ListBox from MS SQL Database" FontSize="25" FontWeight="Bold" Margin="5" HorizontalAlignment="Left"/>
<ListBox Name="lstBox" HorizontalAlignment="Left" VerticalAlignment="Center" ItemsSource="{Binding utilizatori}" SelectionChanged="lstBox_SelectionChanged"
Background="#fff">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" >
<TextBlock Text="{Binding Path=nume, Mode=TwoWay}" Margin="2" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Text="{Binding txtSelectedItem}" Margin="5"/>
<DataGrid x:Name="dGrid" ItemsSource="{Binding ElementName=lstBox, Path=SelectedItems}" SelectedItem="{Binding utiliz}" Height="100"/>
<Button Content="Salveaza modificarea" Command="{Binding SalveazaModificari}" Margin="276,0,309,0">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItems.Count,ElementName=dGrid}"
Value="0">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<GroupBox Header="Adauga Utilizator">
<StackPanel Orientation="Vertical" Background="#a6d9ef" Margin="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
<Border CornerRadius="25" Margin="192,10,159,10" BorderBrush="Red" Background="White" Height="214">
<StackPanel Orientation="Vertical">
<Label Content="Adauga utilizator" FontSize="20" HorizontalContentAlignment="Center" FontWeight="Medium" Margin="2,0,2,10" FontStyle="Italic" VerticalContentAlignment="Top"/>
<Grid Margin="2" Height="120" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="134"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Margin="4,0,197,0" Content="Nume:" VerticalContentAlignment="Center"
HorizontalContentAlignment="Right" Grid.ColumnSpan="2"/>
<TextBox Text="{Binding NumeNou, Mode=TwoWay}" Grid.Row="0" Grid.Column="1" x:Name="txtNume" Margin="9,5,42,5" Width="150" VerticalContentAlignment="Center" HorizontalContentAlignment="Left"/>
<Label Grid.Row="1" Grid.Column="0" Margin="10,0,191,0" Content="Parola : " VerticalContentAlignment="Center" HorizontalContentAlignment="Right" Grid.ColumnSpan="2"/>
<TextBox Text="{Binding ParolaNou, Mode=TwoWay}" Grid.Row="1" Grid.Column="1" x:Name="txtParola" Margin="10,5,41,5" Width="150" VerticalContentAlignment="Center" HorizontalContentAlignment="Left"/>
<CheckBox x:Name="admin" IsChecked="{Binding EadminNou, Mode=TwoWay}" Content="Admin" HorizontalAlignment="Left" Margin="116,5,0,0" Grid.Row="2" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<StackPanel Orientation="Horizontal" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" HorizontalAlignment="Center">
<Button Content="Adauga" x:Name="btnSalveaza" Margin="2,10,2,-10" Width="100" Height="30" Command="{Binding Salveaza}" Background="#80ff00" Foreground="Black" BorderBrush="White"/>
</StackPanel>
</Grid>
</StackPanel>
</Border>
</StackPanel>
</GroupBox>
</StackPanel>
</Window>
Upvotes: 0
Views: 72
Reputation: 35733
after cmd.ExecuteScalar();
is invoked, new user record will be added to database (assuming there were no exceptions). but hte db is not synced with the application immediately.
the simplest way will be to add new user record to ObservableCollection:
cmd.ExecuteScalar();
var u = new Utilizatori {nume = this.NumeNou, parola = this.ParolaNou };
utilizatori.Add();
you probably also need to modify sql command to return the id of created record (see SCOPE_IDENTITY() )
Upvotes: 1