当我将Binding Mode
添加到TwoWay
DataGrid
赢得的节目时,我遇到了这个问题。当我将Binding Mode
保留为默认值时,DataGrid
将会显示为strings
,我找不到问题。
在XAML
我还有3个button
s:Load
(加载表格),Update
和Cancel
(取消所有更改并重新加载{ {1}}直接来自DataGrid
。
以下是我的ObservableCollection
XAML
行
DataGrid
我有一个<DataGrid x:Name="dataGrid" AutoGenerateColumns="True" Canvas.Left="10" Canvas.Top="10" AlternatingRowBackground="LightGreen" Height="245" Width="500" ItemsSource="{Binding Userss.GetValues, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DataContext="{Binding RelativeSource={RelativeSource Self}}"/>
Userss
我创建了Class
,其中我存储了ObservableCollection
SQLite
的数据。
database
}
这是我public class Userss : INotifyPropertyChanged
{
public static SQLiteConnection m_dd = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
public static ObservableCollection<Userss> userCol = new ObservableCollection<Userss>();
public int Id { get; set; }
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
RaisePropertyChanged();
}
}
private Sex _sex;
public Sex Sex
{
get { return _sex; }
set
{
_sex = value;
RaisePropertyChanged();
}
}
private Stations _station;
public Stations Station
{
get { return _station; }
set
{
_station = value;
RaisePropertyChanged();
}
}
private Jobs _job;
public Jobs Job
{
get { return _job; }
set
{
_job = value;
RaisePropertyChanged();
}
}
private DateTime _date;
public DateTime Date
{
get { return _date; }
set
{
_date = value;
RaisePropertyChanged();
}
}
public static ObservableCollection<Userss> GetValues()
{
m_dd.Open();
string sql = "select * from user";
userCol.Clear();
SQLiteCommand cmd = new SQLiteCommand(sql, m_dd);
SQLiteDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string sex1 = reader["sex"].ToString();
string station1 = reader["station"].ToString();
string job1 = reader["job"].ToString();
string data1 = reader["date"].ToString();
userCol.Add(new Userss()
{
Id = Convert.ToInt32(reader["id"]),
Name = reader["name"].ToString(),
Sex = (Sex)Enum.Parse(typeof(Sex), sex1),
Station = (Stations)Enum.Parse(typeof(Stations), station1),
Job = (Jobs)Enum.Parse(typeof(Jobs), job1),
Date = Convert.ToDateTime(data1)
});
}
m_dd.Close();
return userCol;
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName] string caller = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(caller));
}
}
}
public enum Sex
{
Male,
Female
}
public enum Jobs
{
Programmer,
Designer,
Manager,
CTO,
CEO,
}
public enum Stations
{
Desktop,
Laptop,
Tablet
}
MainWindow
}
顺便说一句,我在public partial class MainWindow : Window
{
public SQLiteConnection m_db = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
SQLiteDataAdapter adap;
DataSet ds;
DataTable dt;
SQLiteCommandBuilder cmdbl;
string Query;
public MainWindow()
{
InitializeComponent();
}
private void LoadButton_Click(object sender, RoutedEventArgs e)
{
try
{
m_db.Open();
ObservableCollection<Userss> cUser = Userss.GetValues();
Query = "Select * from user";
adap = new SQLiteDataAdapter(Query, m_db);
ds = new DataSet();
adap.Fill(ds, "Users");
dt = ds.Tables[0];
dataGrid.DataContext = ds.Tables[0].DefaultView;
dataGrid.ItemsSource = dt.DefaultView;
m_db.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void Update_Click(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("Are you sure you want to make those changes?", "Please confirm", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
try
{
cmdbl = new SQLiteCommandBuilder(adap);
adap.Update(ds, "Users");
ds.Tables[0].AcceptChanges();
dataGrid.Items.Refresh();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
this.dataGrid.CancelEdit();
}
private void CancelClick(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("Are you sure you want to cancel those changes?", "Please confirm", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
dataGrid.ItemsSource = Userss.GetValues();
}
else
this.dataGrid.CancelEdit();
}
}
工作。
希望有人可以帮助我。感谢。
答案 0 :(得分:0)
问题是你绑定了一个不起作用的函数。您应绑定到包含要在数据网格中显示的模型列表的公共属性。这样你需要将GetValues
调用移动到其他地方,但是你已经在LoadButton_Click
事件处理程序中拥有了这些代码,所以我会重复使用它。
因此,第一个更改是将您的userCol
- 集合更改为公共属性而不是公共字段,因为绑定仅适用于公共属性,除非您想要提升PropertyChangedEvent
参考您的ObservableCollection
更改。
// old code
public static ObservableCollection<Userss> userCol = new ObservableCollection<Userss>();
// new Code
private static ObservableCollection<Userss> userCol = new ObservableCollection<Userss>();
public static ObservableCollection<Userss> UserCol {
get { return userCol; }
set { userCol = value; RaisePropertyChanged(); }
}
您的GetValues
- 方法不再需要返回类型,因此只需将其更改为无效即可。在内部,将对usercol
的每次调用更改为新的公共属性UserCol
,以便在发生对列表的更改时,GUI现在需要关于它(通过RaisePropertyChanged
例如)
在你的LoadButton_Click
内部你基本上和你的GetValues
功能一样,这也没有多大意义,特别是因为你不再使用你的Userss
模型了。您只需使用此处的GetValues
- 方法重新加载所有数据(您还需要其他事件,例如DataGridLoaded或在启动时填充数据的内容):
private void LoadButton_Click(object sender, RoutedEventArgs e)
{
// ... exception handling
Userss.GetValues();
}
现在只需在xaml视图中绑定到您的集合:
<DataGrid x:Name="dataGrid" AutoGenerateColumns="True" Canvas.Left="10" Canvas.Top="10" AlternatingRowBackground="LightGreen" Height="245" Width="500" ItemsSource="{Binding Userss.UserCol, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DataContext="{Binding RelativeSource={RelativeSource Self}}"/>
请注意,这只是一般的想法,我没有测试此代码,因此您可能需要在视图位置修复它。另外我认为如果你想看一下MVVM设计模式以便以一种很好的方式构建你的代码会很好。