Khu*_*shi 4 c# silverlight wpf xaml mvvm
我正在尝试将数据保存到数据库.
假设我有一个名为Customers三个字段的表:
Id
FirstName
LastName
Run Code Online (Sandbox Code Playgroud)
我使用ADO.Net实体数据模型创建了我的模型.
这是我的ViewModel代码
public class myViewModel : INotifyPropertyChanged
{
private string _firstName;
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
private string _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
protected virtual void OnPropertyChanged(string PropertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(PropertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
Run Code Online (Sandbox Code Playgroud)
这是我的MainWindow.xaml文件:
<Window x:Class="Lab_Lite.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Lab_Lite.ViewModels"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="FirstName" />
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=Explicit}" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="LastName" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding LastName, Mode=TwoWay, UpdateSourceTrigger=Explicit}" />
<Button Grid.Row="2" Grid.Column="1" Content="Save" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
我这里有两个问题:
1. How my ViewModel knows that FirstName property declared in ViewModel is
referenced to FirstName Column in my database?
2. How to save changes to database when UpdateSourceTrigger is set to Explicit?
Run Code Online (Sandbox Code Playgroud)
我想我已经使用Command在某种程度上找到了第二个问题的答案.但我不知道它是否正确,因为我不知道第一个问题的答案.
更新:
假设我有两个这样的表:
顾客:
CustomerID
Name
GenderID //Foreign Key
Run Code Online (Sandbox Code Playgroud)
性别 :
GenderID
Value
Run Code Online (Sandbox Code Playgroud)
现在应该是什么的价值CurrentCustomer.Gender的SaveCustomerChanges方法?
TMa*_*Man 10
我强烈建议您使用数据库优先使用像Entity Framework(EF)这样的ORM,因为您已经创建了数据库.实体框架将自动为您创建您的POCO(模型类,Plain Old C#Objects),并且还将创建一个名为**YourDbName**Contextyour 的类DbContext.此时,每次运行应用程序时,应用程序都会创建一个上下文实例,您将能够使用上下文访问数据库.EF还将跟踪您所做的任何更改,因此以下是您将如何解决问题:
EF生成POCO:
public partial class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在viewmodel中,您可以List<Customer>()从数据库中检索a .
public List<Customer> Customers { get; set; } //Load from context in constructor, really though you should do it in a service layer
public Customer CurrentCustomer { get; set; } //Current customer you need to edit
Run Code Online (Sandbox Code Playgroud)
所以现在viewmodel中有两个选项:为了成为自然MVVM,你不应该将CurrentCustomer绑定到视图.这不符合模式.为了解决这个问题,你可以像上面一样创建单独的属性,然后你可以CurrentCustomer.PropertyName在getter中返回并在setter中使用它,如下所示:
public string FirstName
{
get
{
return CurrentCustomer.FirstName;
}
set
{
CurrentCustomer.FirstName = value;
OnPropertyChanged("FirstName");
}
}
Run Code Online (Sandbox Code Playgroud)
通过这样做,您不必担心将viewmodel属性映射到POCO属性,但是您在视图中所做的任何更改现在都会导致Entity Framework跟踪更改,在这种情况下,您现在需要在保存中完成所有操作方法是打电话dbContext.SaveChanges();.
如果您希望能够进行任何取消或撤消操作,请立即按照现有方式设置属性:
private string _firstName;
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
Run Code Online (Sandbox Code Playgroud)
在您的保存方法中,您必须将viewmodel属性映射到CurrentCustomer的属性,然后应该跟踪更改:
private void SaveCustomerChanges()
{
//Could use Automapper to handle mapping for you.
CurrentCustomer.FirstName = this.FirstName;
CurrentCustomer.LastName = this.LastName;
dbContext.SaveChanges(); //dbContext will be named diff for you
}
Run Code Online (Sandbox Code Playgroud)
此时,更改应该已经完成并更新了数据库表.
现在,如果您不使用Entity Framework,则需要设置某种类型的数据访问层,您可以将其传入Customer对象,然后您需要从数据库中检索该对象并更新其值.
看看这个!
编辑:要打电话,SaveCustomerChanges()您需要使用此方法ICommand.
首先创建一个RelayCommand类:
public class RelayCommand : ICommand
{
private Action<object> _action;
public RelayCommand(Action<object> action)
{
_action = action;
}
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
现在在你的viewmodel中:
public ICommand SaveChangesCommand { get; set; }
Run Code Online (Sandbox Code Playgroud)
在您的viewmodel构造函数中
SaveChangesCommand = new RelayCommand(SaveCustomerChanges);
Run Code Online (Sandbox Code Playgroud)
然后在XAML中连接SaveChangesCommand:
<Button Content="Save" Command="{Binding SaveChangesCommand }" />
Run Code Online (Sandbox Code Playgroud)
现在,当您单击"保存"时,该命令应该触发该SaveCustomerChanges()方法.
| 归档时间: |
|
| 查看次数: |
19884 次 |
| 最近记录: |