【问题标题】:Add Rows In a empty dataGrid在空的dataGrid中添加行
【发布时间】:2015-12-27 16:42:27
【问题描述】:

我正在构建一个 MVVM - WPF 应用程序。 我很少有 CRUD 操作可以正常工作的数据网格。

现在,我希望 dataGrid 在开始时始终为空,当然我可以在其中添加行。所以我可以填写它,但是当我点击保存时,什么都没有保存。

为什么?

视图模型:

public class InvoiceViewModel : ViewModelBase
{
    public Context ctx = new Context();
    public InvoiceViewModel()
    {
        this.Collection = new ObservableCollection<Invoice>();
    }
    private ObservableCollection<Invoice> collection;
    public ObservableCollection<Invoice> Collection
    {
        get
        {
            return collection;
        }
        set
        {
            collection = value;
            OnPropertyChanged("Collection");
        }
    }
    private Invoice _selected;
    public Invoice Selected
    {
        get
        {
            return _selected;
        }
        set
        {
            _selected = value;
            OnPropertyChanged("Selected");
        }
    }
    private void Get()
    {
        ctx.Invoices.ToList().ForEach(invoice => ctx.Invoices.Local.Add(invoice));;
        Collection = ctx.Invoices.Local;
    }
    private void Save()
    {
        foreach (Invoice item in Collection)
        {
            if (ctx.Entry(item).State == System.Data.Entity.EntityState.Added)
            {
                ctx.Invoices.Add(item);
            }
        }
        ctx.SaveChanges();
    }
    private void Delete()
    {
        var id = Selected;
        var invoice = (from i in ctx.Invoices
                    where i.idInvoice == id.idInvoice
                    select i).SingleOrDefault();
        Collection.Remove(invoice);
    }

    #region "Command"
    // private ICommand getCommand;
    private ICommand saveCommand;
    private ICommand removeCommand;

    /*public ICommand GetCommand
    {
        get
        {
            return getCommand ?? (getCommand = new RelayCommand(p => this.Get(), p => this.CanGet()));
        }
    }
    private bool CanGet()
    {
        return true;
    }*/
    public ICommand SaveCommand
    {
        get
        {
            return saveCommand ?? (saveCommand = new RelayCommand(p => this.Save(), p => this.CanSave()));
        }
    }
    private bool CanSave()
    {
        return true;
    }
    public ICommand DeleteCommand
    {
        get
        {
            return removeCommand ?? (removeCommand = new RelayCommand(p => this.Delete(), p => this.CanDelete()));
        }
    }
    public bool CanDelete()
    {
        if (Selected != null)
            return true;
        else
            return false;
    }
    #endregion
}

查看:

<Page.Resources>
    <local:InvoiceViewModel x:Key="invoice" />
    <local:ShopViewModel x:Key="shop" />
    <local:SupplierViewModel x:Key="supplier" />
    <local:ProductViewModel x:Key="product" />
    <DataTemplate x:Key="ProductDataTemplate">
        <TextBlock Text="{Binding product}" />
    </DataTemplate>
</Page.Resources>
<DataGrid x:Name="dataGridInvoice"
          Margin="5"
          Grid.Row="1"
          ItemsSource="{Binding Collection}"
          AutoGenerateColumns="False"
          SelectedItem="{Binding Selected, Mode=TwoWay}"
          SelectionMode="Extended"
          SelectionUnit="FullRow">
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="dataGridTextColumn"
                            Header="Supplier Invoice Nb"
                            Width="*" />
        <DataGridComboBoxColumn Header="Ref Supplier"
                                ItemsSource="{Binding Products, Source={StaticResource supplier}, Mode=OneWay}"
                                DisplayMemberPath="refsup"
                                SelectedValueBinding="{Binding refSupp}"
                                SelectedValuePath="refsup"
                                Width="*" />
        <DataGridTextColumn Header="Unit"
                            Binding="{Binding unit, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                            Width="*" />
        <DataGridTextColumn Header="Quantity"
                            Binding="{Binding quantity, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                            Width="*" />
        <DataGridTextColumn Header="Prix/MOQ"
                            Binding="{Binding unitPrice, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                            Width="*" />
        <DataGridTextColumn Header="Total Price"
                            Binding="{Binding totalPrice, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                            Width="*" />
    </DataGrid.Columns>
</DataGrid>
<StackPanel Orientation="Horizontal">
    <Button  x:Name="BtnDelete"
             Content="Delete"
             Command="{Binding DeleteCommand}"
             HorizontalAlignment="Center"
             Margin="100,5,5,5"
             Width="85" />
    <Button  x:Name="BtnAdd"
             Content="Save"
             Command="{Binding SaveCommand}"
             HorizontalAlignment="Center"
             Margin="20,5,5,5"
             Width="85" />
</StackPanel>

【问题讨论】:

  • 您是否正在收集对象?
  • 是的,我愿意。它有效。
  • 那么你到底是从哪里得到问题的?
  • 其实我不想拿这些东西。我想要一个空的dataGrid,我可以在其中添加将保存在数据库中的新行。但什么都没有保存。
  • 我相信它永远不会进入 if 条件 ((ctx.Entry(item).State == System.Data.Entity.EntityState.Added) ),是吗?

标签: c# wpf mvvm datagrid


【解决方案1】:

您有这个方法,它实际上将Collection 绑定到实体集的缓存本地。没有绑定,添加的项更难保存:

private void Get() {
        ctx.Invoices.ToList().ForEach(invoice => ctx.Invoices.Local.Add(invoice));;
        Collection = ctx.Invoices.Local;
}

其实也可以这样加载所有发票并缓存到本地:

private void Get() {
   ctx.Invoices.Load();
   Collection = ctx.Invoices.Local;
}

但是,正如您所说,您首先需要一个空数据网格(仅用于添加),然后您可以重构 Get 方法以接受一个布尔值,指示是否应首先从 db 加载数据:

private void Get(bool loadDataFirst) {
   if(loadDataFirst) ctx.Invoices.Load();
   Collection = ctx.Invoices.Local;
}

现在通过使用Get 方法而不首先加载数据,您的Collection 仍然很好地绑定到Local 缓存(应该是空的)。向Collection 添加新项目后,Local 将自动添加这些项目,Save 只需调用SaveChanges

private void Save() {
   ctx.SaveChanges();
}

Get 方法应该在构造函数中使用,像这样替换this.Collection = new ObservableCollection&lt;Invoice&gt;();

public InvoiceViewModel() {
   Get(false);
}

【讨论】:

  • 我没有看到对这个方法的调用!我错过了什么?
  • @Nikita 你指的是哪种方法?
  • Get() 你说的方法。
  • @Nikita 您可以仔细滚动 OP 的代码,它是 Save() 方法上方的私有方法。之前可能会在 OP 将所有数据加载到网格中时使用它,但他现在想要一个空列表(所以他没有使用 Get)。
  • 不是声明,我的意思是调用 Get() 函数。总之,解决了!! :)
猜你喜欢
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 2016-11-09
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多