我最近开始学习WPF,自然地,我尝试理解MVVM,根据我的阅读,这是对wpf应用程序进行编程的正常方法。
我从互联网上获取了一个用于用户管理的基本资源,然后开始从那里进行构建。基本上,我有一个通过ObservableCollection绑定到sql数据库的列表框,该列表框显示用户名,并且当选择一个项目时,该用户的所有详细信息都将显示在datagrid中。
在窗口中,我还有一个分组框,您可以在其中向数据库添加新用户,这就是问题所在:单击添加按钮后,listox没有用新用户更新-我需要关闭并重新打开应用程序将新用户显示在列表框中。
我在哪里错了?
我的模型班:
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));
}
}
}
}
我的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; }
}
我的观点:
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);
}
}
}
我的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>
答案 0 :(得分:1)
在调用cmd.ExecuteScalar();
之后,新的用户记录将被添加到数据库中(假设没有例外)。但是hte db不会立即与应用程序同步。
最简单的方法是将新的用户记录添加到ObservableCollection:
cmd.ExecuteScalar();
var u = new Utilizatori {nume = this.NumeNou, parola = this.ParolaNou };
utilizatori.Add();
您可能还需要修改sql命令以返回创建的记录的ID(请参见SCOPE_IDENTITY() )