tiempo - eliminar datos de un datagridview c#
No se puede actualizar Datagrid y guardar cambios en la base de datos (2)
Para que la columna "total" en DataGrid
se actualice, la clase Product
debe implementar la interfaz INotifyPropertyChanged y generar el evento PropertyChanged
para la propiedad Total
:
private double _total;
public double Total
{
get { return _total; }
set { _total = value; OnPropertyChanged("Total"); }
}
Y para que pueda guardar el valor en la base de datos, necesita asignar la propiedad Total
a una columna en su tabla de base de datos, tal como lo hizo (afortunadamente) con las otras columnas.
Tengo una cuadrícula de datos, una ObservableCollection de tipos de productos en un ViewModel y una implementación de EventToCommand como se muestra a continuación. Me gustaría actualizar la Columna total del producto de Columna de cantidad y costo y guardar los cambios sin usar el código malvado detrás o Windows Forms DataGridView. ¿Cómo puedo conseguir esto? Cuadrícula de datos:
<DataGrid x:Name="dataGrid" Margin="5,5,10,5" AutoGenerateColumns="False" HorizontalAlignment="Stretch" ItemsSource="{Binding ProductList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Stretch" Height="566" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="CellEditEnding" SourceObject="{Binding ElementName=Control}">
<cmd:EventToCommand Command="{Binding EndEdit}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
<DataGridTextColumn x:Name="Id" Binding="{Binding Path=Id, Mode=TwoWay}" Header="Id"/>
<DataGridTextColumn x:Name="name" Binding="{Binding Path=Name, Mode=TwoWay}" Header="Name"/>
<DataGridTextColumn x:Name="cost" Binding="{Binding Path=Cost, Mode=TwoWay}" Header="Cost"/>
<DataGridTextColumn x:Name="Quantity" Binding="{Binding Path=Quantity, Mode=TwoWay}" Header="Quantity"/>
<DataGridTextColumn x:Name="total" Binding="{Binding Path=Total, Mode=TwoWay}" Header="Total"/>
</DataGrid.Columns>
Luego en ViewModel
private ObservableCollection<Product> _product;
public ObservableCollection<Product> MyProduct
{
get
{
return _product;
}
set
{
Set(ref _product, value);
}
}
public ProductViewModel(IDataService proxy)
{
_proxy = proxy;
LoadCommand = new RelayCommand(DoGetProducts);
EndEdit = new RelayCommand<DataGridCellEditEndingEventArgs>(DoEndEdit);
}
private void DoEndEdit(DataGridCellEditEndingEventArgs obj)
{
DataGridRow row = obj.Row;
Product p = (Product)row.Item;
p.Total = p.Cost*p.Quantity;
_proxy.SaveAll();
}
Luego en el Modelo:
public class DataService : IDataService
{
ProductEntities context;
public DataService()
{
context = new ProductEntities();
}
public ObservableCollection<Product> GetProducts(){
ObservableCollection<Product> products = new ObservableCollection<Product>();
foreach(var p in context.Products.Tolist()){
products.add(p);
}
return products;
}
public void SaveAll()
{
context.SaveChanges();
}
}
La cuadrícula de datos está cargando productos pero no está actualizando el Total cuando se modifican el Costo y la Cantidad. Además, no guarda los cambios en la base de datos
Cambia tu Xaml como dar a continuación
<DataGrid x:Name="dataGrid" Margin="5,5,10,5" AutoGenerateColumns="False" HorizontalAlignment="Stretch" ItemsSource="{Binding ProductList}" VerticalAlignment="Stretch" Height="566" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="RowEditEnding" ">
<cmd:EventToCommand Command="{Binding EndEdit}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
<DataGridTextColumn x:Name="Id" Binding="{Binding Path=Id, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Id"/>
<DataGridTextColumn x:Name="name" Binding="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Name"/>
<DataGridTextColumn x:Name="cost" Binding="{Binding Path=Cost, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Cost"/>
<DataGridTextColumn x:Name="Quantity" Binding="{Binding Path=Quantity, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Quantity"/>
<DataGridTextColumn x:Name="total" Binding="{Binding Path=Total, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Header="Total"/>
</DataGrid.Columns>
Y en View Model you Bindings sea como
public BindingList<Product> ProductList
{
get
{
return _proxy.ProductList;
}
}
Y el comando EndEdit debería ejecutar la siguiente función
private void ExecuteEndEdit(DataGridRowEditEndingEventArgs param)
{
var product = param.Row.Item as Product;
var result = ProductList.FirstOrDefault(p => p.Id == product.Id);
var index= ProductList.IndexOf(result);
result.Total = result.Cost * result.Quantity;
ProductList.ResetItem(index);
}
Su IDataService puede exponer lista de vinculación como
public class DataService : IDataService
{
ProductEntities context;
public DataService()
{
context = new ProductEntities();
}
public BindingList<Product> ProductList
{
get
{
//EDIT: YOU HAVE TO CALL context.Products.Load(); OR IT WILL RETURN EMPTY RESULTS
context.Products.Load();
return context.Products.Local.ToBindingList<Product>();
}
}
public void SaveAll()
{
context.SaveChanges();
}
}
El Context.Save guardará su código.