无法在另一个DataGrid(WPF)的RowDetailsTemplate内的DataGrid中保存添加或删除行

时间:2017-02-10 23:19:32

标签: c# wpf entity-framework datagrid rowdetailstemplate

我正在编写一个使用WPF和实体框架的人力资源安全跟踪应用程序,我想要显示和编辑安全事件网格,并且在每个选定的事件下,将是由于事件而丢失数小时的网格。这意味着DataGrid用于事件的DataGrid的RowDetailsTemplate内的小时数。

我目前可以保存对现有小时行所做的更改,但我无法保存对此内部DataGrid的添加或删除。我的相关型号代码:

[Table("hr.safety_incident")]
public partial class SafetyIncident
{
    [Key]
    [Column(TypeName = "numeric")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public decimal incident_id { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime incident_date { get; set; }

    [Required]
    [StringLength(30)]
    public string incident_type { get; set; }
}

// EDIT: forgot this part of the class
public partial class SafetyIncident    // In another file
{
    protected ObservableCollection<SafetyHours> _lostHoursDetails;

    [NotMapped]
    public ObservableCollection<SafetyHours> LostHoursDetails
    {
        get { return _lostHoursDetails; }
        set
        {
            if (_lostHoursDetails != value)
            {
                _lostHoursDetails = value;
            }
        }
    }
}

[Table("hr.safety_hours")]
public partial class SafetyHours
{
    [Key]
    [Column(TypeName = "numeric")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public decimal safety_hours_id { get; set; }

    [Column(TypeName = "numeric")]
    public decimal incident_id { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime safety_hours_date { get; set; }

    [Column(TypeName = "numeric")]
    public decimal restricted_hours { get; set; }

    [Column(TypeName = "numeric")]
    public decimal lost_hours { get; set; }
}

相关XAML:

    

<DataGrid x:Name="dtgAllIncidents" AutoGenerateColumns="False" 
        ItemsSource="{Binding Source={StaticResource safetyIncidentViewSource}}" 
        RowDetailsVisibilityMode="VisibleWhenSelected">
    <DataGrid.Columns>
        <DataGridTemplateColumn x:Name="incident_dateColumn" Header="Incident Date" Width="110" SortMemberPath="incident_date">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <DatePicker IsHitTestVisible="False" 
                        SelectedDate="{Binding incident_date, Mode=TwoWay, NotifyOnValidationError=true, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=true}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <DatePicker SelectedDate="{Binding incident_date, Mode=TwoWay, NotifyOnValidationError=true, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=true}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="Incident Type" Binding="{Binding incident_type}"/>
    </DataGrid.Columns>
    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Enter data into the blank row to add lost and restricted hours.”/>
                <DataGrid x:Name="dtgLostHoursDetails" ItemsSource="{Binding LostHoursDetails}" AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="True">
                    <DataGrid.Columns>
                        <DataGridTemplateColumn x:Name="incident_dateColumn" Header="Month in Which Hours Lost">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <DatePicker IsHitTestVisible="False"
                                            SelectedDate="{Binding safety_hours_date, Mode=TwoWay, NotifyOnValidationError=true, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=true}"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                            <DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <DatePicker SelectedDate="{Binding safety_hours_date, Mode=TwoWay, NotifyOnValidationError=true, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=true}"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellEditingTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Width="SizeToHeader" Header="Lost Hours" Binding="{Binding lost_hours}"/>
                        <DataGridTextColumn Width="SizeToHeader" Header="Restricted Hours" Binding="{Binding restricted_hours}"/>
                    </DataGrid.Columns>
                </DataGrid>
            </StackPanel>
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
</DataGrid>

相关代码隐藏:

private ObservableCollection<SafetyIncident> _incidents;
private SafetyIncidentsViewModel _incidentsVM = new SafetyIncidentsViewModel();

private void mniIncidents_Click(object sender, RoutedEventArgs e)
{
    CollectionViewSource safetyIncidentViewSource = ((CollectionViewSource)this.FindResource("safetyIncidentViewSource")));
    _incidents = _incidentsVM.GetIncidents();
    safetyIncidentViewSource.Source = _incidents;
}
private void btnSaveIncidents_Click(object sender, RoutedEventArgs e)
{
    _incidentsVM.SaveChanges();
    dtgAllIncidents.Items.Refresh();
}

...

public class SafetyIncidentsViewModel
{
    private Corp_DB _context = new Corp_DB();

    public ObservableCollection<SafetyIncident> GetIncidents()
    {
        ObservableCollection<SafetyIncident> results = null;
        LoadSafetyIncidents();
        results = _context.safety_incident.Local;
        return results;
    }

    private void LoadSafetyIncidents()
    {
        _context.safety_incident.OrderBy(si => si.incident_date).Load();
        _context.safety_hours.Load();
        foreach (var i in _context.safety_incident)
        {
            var lostHours = new ObservableCollection<SafetyHours>();
            foreach (var h in _context.safety_hours.Where(sh => sh.incident_id == i.incident_id).OrderBy(sh => sh.safety_hours_date))
            {
                lostHours.Add(h);
            }
            i.LostHoursDetails = lostHours;
        }
    }

    public void SaveChanges()
    {
        // Assign new hours rows their safety incident.  Open to more automatic way...
        foreach (var si in _context.safety_incident)
        {
            foreach (var sh in si.LostHoursDetails.Where(h => h.incident_id == 0))
            {
                sh.incident_id = si.incident_id;
            }
        }
        _context.SaveChanges();
    }

...

另一个复杂点:在_context.SaveChanges调用之前,新的事件行(外部网格)的incident_id为0,那么任何新的小时行(内部网格)如何知道为此保存的内容?在初次通话后还需要做些额外的事情吗,包括第二次通话?感谢...

PS是的,我知道我的MVVM并不纯粹,我只需要一些有用的东西。

0 个答案:

没有答案