使用datagrid并利用触发的事件在数据库上重复输入 [英] Duplicate entry on the database while using datagrid and utilizing triggered event

查看:112
本文介绍了使用datagrid并利用触发的事件在数据库上重复输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以以某种方式禁用Datagrids在绑定数据库(在这种情况下为Entity Framework)中调用添加和保存方法的功能?我正在获得重复,我认为它是由datagrid本身发起的。

Can I somehow disable the Datagrids ability to invoke Add and Save methods on the binded database, in this case Entity Framework? I'm getting duplicate and I assume its initiated by the datagrid itself.

我使用datagrid通过其$ code添加新元素DataGridRowEditEndingEventArgs 触发器。通过使用Mvvm Lights通用 RelayCommand viewModel 我触发了这种方法:

I'm using datagrid to add new element via its DataGridRowEditEndingEventArgs trigger. By using Mvvm Lights generic RelayCommand on viewModel I'm triggering this method:

private void DataGridRowEditEndingExecute(DataGridRowEditEndingEventArgs e)
{
    var device = new Device();
    var newDevice = e.Row.DataContext as Device;
    if (_isInsertMode)
    {
        if (newDevice != null)
        {
            var insertRecord = MessageBox.Show("Do you want to add " + newDevice.Name + " as a new device?", "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (insertRecord == MessageBoxResult.Yes)
            {
                device.DeviceId = 0;
                device.Name = newDevice.Name;
                device.Supplier = newDevice.Supplier;
                device.Category = newDevice.Category;
                device.Description = newDevice.Description;
                device.TimeCreated = DateTime.Now;
                _context.Devices.AddDevice(device);
                _context.Devices.Load();
                _context.Complete();
                RaisePropertyChanged(() => DeviceCollection);
                MessageBox.Show(device.Name + " has being added!", "Inserting Record", MessageBoxButton.OK,
                    MessageBoxImage.Information);
            }
            else
            {
                _context.Devices.Load();
                RaisePropertyChanged(() => DeviceCollection);
            }
            _context.Complete();
        }
    }
}

_context.Complete(); 总是将两套实体保存到数据库中。一个具有正确的时间戳,一个没有它。之后,最后一个 _context.Complete()调用删除没有时间戳的那个

The _context.Complete(); always saves two sets of the entity into database. One with the correct timestamp and one without it. After this the following last _context.Complete() call removes the one without the timestamp?

这是datagrid xaml :

Here's the datagrid xaml:

<DataGrid 
                  x:Name="DeviceListDataGrid" 
                  Margin="0,25,0,0"
                  Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6"
                  AutoGenerateColumns="False" 
                  EnableRowVirtualization="True" 
                  AlternatingRowBackground="LightBlue" 
                  AlternationCount="2" 
                  RowDetailsVisibilityMode="VisibleWhenSelected"
                  ItemsSource="{Binding DeviceDatabaseViewModel.DeviceCollection}" 
                  SelectedItem="{Binding DeviceDatabaseViewModel.SelectedDevice}">
            <DataGrid.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="DarkCyan"/>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="DarkCyan"/>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="DeviceIdentification" Header="Id" Width="200*" Binding="{Binding DeviceId, UpdateSourceTrigger=PropertyChanged}"  />
                <DataGridTextColumn x:Name="DeviceName" Header="Name" Width="200*" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  />
                <DataGridTextColumn x:Name="DeviceDescriptionColumn" Header="Description" Width="200*" Binding="{Binding Description, UpdateSourceTrigger=PropertyChanged}"/>
                <DataGridTextColumn x:Name="DeviceSupplier" Header="Supplier" Width="150*" Binding="{Binding Supplier, UpdateSourceTrigger=PropertyChanged}"/>
                <DataGridTextColumn x:Name="DeviceCategory" Header="Category" Width="150*" Binding="{Binding Category, UpdateSourceTrigger=PropertyChanged}"/>
            </DataGrid.Columns>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="RowEditEnding">
                    <command:EventToCommand PassEventArgsToCommand="True" Command="{Binding DeviceDatabaseViewModel.DataGridRowEditEndingCommand}"/> 
                </i:EventTrigger>
                <i:EventTrigger EventName="PreviewKeyDown">
                    <command:EventToCommand PassEventArgsToCommand="True" Command="{Binding DeviceDatabaseViewModel.DataGridPreviewKeyDownCommand}"/> 
                </i:EventTrigger>
                <i:EventTrigger EventName="AddingNewItem">
                    <command:EventToCommand PassEventArgsToCommand="True" Command="{Binding DeviceDatabaseViewModel.DataGridAddingNewItemCommand}"/> 
                </i:EventTrigger>
                <i:EventTrigger EventName="BeginningEdit">
                    <command:EventToCommand PassEventArgsToCommand="True" Command="{Binding DeviceDatabaseViewModel.DataGridBeginningEditCommand}"/> 
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </DataGrid>

,并将datagrid绑定到此ICollectionView中(可能不是最正确的方法?)

and the datagrid is binded into this ICollectionView (maybe not the most correct approach?)

public ICollectionView DeviceCollection
{
    get
    {
        _context.Devices.Load();
        _deviceCollection = CollectionViewSource.GetDefaultView(_context.Devices.GetLocal());
        return _deviceCollection;
    }
    set
    {
        if (_deviceCollection == null)
        {
            return;
        }
        _deviceCollection = value;
        RaisePropertyChanged("DeviceCollection");
    }
}


推荐答案

原因是你触发 DataGridRowEditEndingExecute 函数,然后在这里添加项。在你的 ObservableCollection (说它的名字 o )有这个事件: o.CollectionChanged + = o_CollectionChanged; 。你应该使用它,而不是手动添加项目。

The reason is you trigger DataGridRowEditEndingExecute function then add item here. In your ObservableCollection (say it name o) have this event: o.CollectionChanged += o_CollectionChanged;. You should use this instead, don't add item manually.

using System.Collections.Specialized;

bool isAddedbyApp = false;
void o_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add) // User add new item
    {
        foreach(var item in e.NewItems)
        {
            if (!isAddedbyApp)
            {
                var entity = item as Device; // or your Model
                // Do some thing here: ask user, ..., validate value
                // If you don't want this item, you call call remove function to remove it
            }
        }
    }
}

您还有检查您的应用程序或用户在处理之前是否添加了项目。

You also have check if items is added by your app or user before process it.

当您的应用程序(而不是由用户)添加项目时,设置 isAddedbyApp = true; 。完成后,设置 isAddedbyApp = false;

When an item is added by your app (not by user) set isAddedbyApp = true;. When finished, set isAddedbyApp = false;

这篇关于使用datagrid并利用触发的事件在数据库上重复输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆