【发布时间】:2019-09-10 07:57:35
【问题描述】:
我正在尝试通过构建一个利用 INotifyPropertyChange 的项目来学习 WPF 中的 MVVM,然后我计划添加命令,但我目前无法使用 INotify 更新接口。
我尝试了不同的接口实现,但是当我通过按钮“添加”添加新值时仍然没有得到新值,该按钮只是将固定名称和 ID 添加到我的 SQL 数据库中,请注意该值确实添加到了数据库中
这是 MainWindowView.Xaml
<Window x:Class="simpleMvvM1.MainWindow"
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"
mc:Ignorable="d"
xmlns:viewmodel="clr-namespace:simpleMvvM1.ViewModels"
Title="MainWindow" Height="880" Width="800">
<Window.DataContext>
<viewmodel:MainWindowViewModel/>
</Window.DataContext>
<Grid >
<StackPanel>
<TextBlock Text="{Binding userCollection}" Margin="10" >
</TextBlock>
<ListBox ItemsSource="{Binding userCollection}" Margin="0 5 0 5" Height="100" Name="ListView">
<ListBox.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Label Content="{Binding userid }"></Label>
<Label Content="{Binding username}"></Label>
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Text="Name" Name="NameTextBlock"></TextBlock>
<TextBox x:Name="NameTextBox"></TextBox>
<TextBlock Text="ID" Name="IDTextBlock"></TextBlock>
<TextBox x:Name="IDTextBox"></TextBox>
<Grid>
<Grid.ColumnDefinitions></Grid.ColumnDefinitions>
<DataGrid ItemsSource="{Binding Users_datatable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="UserDataGrid" Height="200"></DataGrid>
</Grid>
<Grid Margin="0 10">
<Grid.ColumnDefinitions></Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding userCollection}" x:Name="UserListView" Height="200">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ListViewItem Content="{Binding userid}"></ListViewItem>
<ListViewItem Content="{Binding username}"></ListViewItem>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Button
Name="AddButton" Click="AddButton_Click"
>Add</Button>
<Button>Delete</Button>
<Button>Update</Button>
<Button
x:Name="ClearButton"
Content="Clear" Click="ClearButton_Click"
></Button>
<Button
Content="Close"
/>
</StackPanel>
</Grid>
</Window>
这是 MainWindowViewModel.cs
using simpleMvvM1.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace simpleMvvM1.ViewModels
{
class MainWindowViewModel
{
//Connection string setup. See App for more informatiom
static string myconnection = ConfigurationManager.ConnectionStrings["simpleMvvM1.Properties.Settings.myTestDbConnectionString"].ConnectionString;
//DataTable to store the database tables we are using
public DataTable Users_datatable { get; set; } = new DataTable();
//collection of the UserTable information
public ObservableCollection<Models.UserNames> userCollection { get; set; } = new ObservableCollection<UserNames>();
/// <summary>
/// Constructor Situation
/// </summary>
public MainWindowViewModel()
{
getAllUsersNamesTest();
}
public ObservableCollection<String> getAllUsersNames()
{
SqlConnection con = new SqlConnection(myconnection);
SqlCommand cmd = new SqlCommand("Select Username from UserTable;");
con.Open();
SqlDataAdapter adp = new SqlDataAdapter(cmd);
ObservableCollection<String> userNames = new ObservableCollection<String>();
userNames.Add("ImJhonny");
return userNames;
}
/// <summary>
/// Fills in the DataTable and the Observable Collection for us to use.
/// </summary>
public void getAllUsersNamesTest()
{
//Connects to our database
SqlConnection con = new SqlConnection(myconnection);
//Saves the command to SqlCommand cmd
SqlCommand cmd = new SqlCommand("Select*From UserTable;", con);
//Opens Connection
con.Open();
//Stores the table for this session
SqlDataAdapter adp = new SqlDataAdapter(cmd);
Users_datatable = new DataTable(); //references the object
//Filles data Table
adp.Fill(Users_datatable);
//Closes connection
con.Close();
for (int i = 0; i < Users_datatable.Rows.Count; i++)
{
userCollection.Add(new Models.UserNames
{
username = Users_datatable.Rows[i]["UserName"].ToString(),
userid = (int)Users_datatable.Rows[i]["UserID"]
});
}
}
public bool insertIntoDb()
{
//Connects to our database
SqlConnection con = new SqlConnection(myconnection);
//Create a Boolean variable and set its default value to false
bool isSuccess = false;
try
{
//Saves the command to SqlCommand cmd
SqlCommand cmd = new SqlCommand("INSERT INTO UserTable(UserID, UserName) Values (@userid , @username);", con);
cmd.Parameters.AddWithValue("@username", "Churro");
cmd.Parameters.AddWithValue("@userid", 13);
//Opens Connection
con.Open();
int rows = cmd.ExecuteNonQuery();
if (rows > 0)
{
isSuccess = true;
}
else
{
isSuccess = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
con.Close();
}
return isSuccess;
}
public void ClearTextBoxes()
{
MainWindow mw = new MainWindow();
mw.NameTextBlock.Text = "";
mw.IDTextBlock.Text = "";
}
}
}
最后是 UserNames.cs 模型文件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace simpleMvvM1.Models
{
class UserNames : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
private int UserID =00;
public int userid
{
get { return UserID; }
set
{
UserID = value;
NotifyPropertyChanged("userid");
}
}
private string UserName;
public string username
{
get { return UserName; }
set
{
UserName = value;
NotifyPropertyChanged("username");
}
}
}
}
当我按下我的 ADD 按钮时,我预计视图会发生变化,其背后的代码只是从 MainWindowView.Xaml 文件中调用 insertIntoDb() 方法
MainWindowViewModel mwvm = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
}
private void AddButton_Click(object sender, RoutedEventArgs e)
{
mwvm.insertIntoDb();
}
【问题讨论】:
-
"utalizes INotifyPropertyChange" 还不够,目前
mwvm.insertIntoDb()没有发出任何通知。尝试清除userCollection并在其末尾调用getAllUsersNamesTest()以查看差异,尽管这并不理想。