如何使TwoWay绑定工作

时间:2016-11-17 13:35:25

标签: c# sqlite xaml data-binding datagrid

当我将Binding Mode添加到TwoWay DataGrid赢得的节目时,我遇到了这个问题。当我将Binding Mode保留为默认值时,DataGrid将会显示为strings,我找不到问题。 在XAML我还有3个button s:Load(加载表格),UpdateCancel(取消所有更改并重新加载{ {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(); } } 工作。

希望有人可以帮助我。感谢。

1 个答案:

答案 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设计模式以便以一种很好的方式构建你的代码会很好。