首页 > 解决方案 > 在 DataGridView 中显示空组合框内容?

问题描述

我创建了一个用户控制页面 (SubPODetailView.xaml),其中包含一些实体“从 SubPO.cs 定义的实体”和一个 datagridview“ gridview 是一个名为 SubInvoice.cs 的单独类”,一切顺利,但在 datagridview 中,一个of entity是一个组合框显示,这里的问题是运行程序时这个组合框的集合列表不显示。

子PO.cs

public class SubInvoice
{
    public int Id { get; set; }

    [Required]
    public string InvoiceName { get; set; }

    public DateTime Date { get; set; }

    public decimal Amount { get; set; }

    public List<string> Status{ get; set; }

    public int SubPOId { get; set; }

    public SubPO SubPO { get; set; }
}

Configuration.cs(在迁移文件夹中)

context.SubInvoices.AddOrUpdate(i => i.InvoiceName,
            new SubInvoice
            {
                InvoiceName = "Invoice1",
                Date = new DateTime(2020, 5, 26),
                Amount = 1200,
                SubPOId=context.SubPOs.First().Id,
                Status = new List<string>() { "Open", "Closed", "Pending" }
            });

SubPODetailViewModel.cs

 <DockPanel Grid.Row="12" Margin="10">
        <StackPanel DockPanel.Dock="Right" Width="86">
            <Button Content="Add"  Margin="10"
            Command="{Binding AddInvoiceCommand}"/>
            <Button Content="Remove"  Margin="10"
            Command="{Binding RemoveInvoiceCommand}"/>
        </StackPanel>
        <DataGrid ItemsSource="{Binding Invoices}" 
            SelectedItem="{Binding SelectedInvoice,Mode=TwoWay}"
            AutoGenerateColumns="False" RowHeaderWidth="0" >
            
            <DataGrid.Columns>
                <DataGridTextColumn Header="Invoices" Width="*"
                                    Binding="{Binding InvoiceName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

            <DataGridTemplateColumn Header="Status" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <DatePicker SelectedDate="{Binding Date,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <DataGridTextColumn Header="Amount" Width="*" Binding="{Binding Amount,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

            <DataGridTemplateColumn Header="Status" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Status,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
            
        </DataGrid>
    </DockPanel>

SubPODetailViewModel.cs(模型)

    namespace SubBV.UI.ViewModel
{
    public class SubPODetailViewModel : DetailViewModelBase, ISubPODetailViewModel
    {
        private ISubPORepository _subPORepository;
        private IMessageDialogService _messageDialogService;
        private SubPOWrapper _subPO;
        private SubInvoiceWrapper _selectedInvoice;

        public SubPODetailViewModel(IEventAggregator eventAggregator,
            IMessageDialogService messageDialogService,
            ISubPORepository subPORepository) : base(eventAggregator)
        {
            _subPORepository = subPORepository;
            _messageDialogService = messageDialogService;

            AddInvoiceCommand = new DelegateCommand(OnAddInvoiceExecute);
            RemoveInvoiceCommand = new DelegateCommand(OnRemoveInvoiceExecute, OnRemoveInvoiceCanExecute);

            Invoices = new ObservableCollection<SubInvoiceWrapper>();

        }

        public SubPOWrapper SubPO
        {
            get { return _subPO; }
            private set
            {
                _subPO = value;
                OnPropertyChanged();
            }
        }

        public SubInvoiceWrapper SelectedInvoice
        {
            get { return _selectedInvoice; }
            set
            {
                _selectedInvoice = value;
                OnPropertyChanged();
                ((DelegateCommand)RemoveInvoiceCommand).RaiseCanExecuteChanged();
            }
        }

        public ICommand AddInvoiceCommand { get; }
        public ICommand RemoveInvoiceCommand { get; }

        public ObservableCollection<SubInvoiceWrapper> Invoices { get; }

        public override async Task LoadAsync(int? subPOId)
        {
            var subPO = subPOId.HasValue
                ? await _subPORepository.GetByIdAsync(subPOId.Value)
                : CreateNewSubPO();
            InitializeSubInvoice(subPO.Invoices);
        }

    private void InitializeSubInvoice(ICollection<SubInvoice> invoices)
    {
        foreach (var wrapper in Invoices)
        {
            wrapper.PropertyChanged -= SubInvoiceWrapper_PropertyChanged;
        }
        Invoices.Clear();
        foreach (var subInvoice in invoices)
        {
            var wrapper = new SubInvoiceWrapper(subInvoice);
            Invoices.Add(wrapper);
            wrapper.PropertyChanged += SubInvoiceWrapper_PropertyChanged;
        }
    }

    private void SubInvoiceWrapper_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (!HasChanges)
        {
            HasChanges = _subPORepository.HasChanges();
        }
        if (e.PropertyName == nameof(SubInvoiceWrapper.HasErrors))
        {
            ((DelegateCommand)SaveCommand).RaiseCanExecuteChanged();
        }
    }

    private void InitializeSubPO(SubPO subPO)
    {
        SubPO = new SubPOWrapper(subPO);
        SubPO.PropertyChanged += (s, e) =>
        {
            if (!HasChanges)
            {
                HasChanges = _subPORepository.HasChanges();
            }
            if (e.PropertyName == nameof(SubPO.HasErrors))
            {
                ((DelegateCommand)SaveCommand).RaiseCanExecuteChanged();
            }
        };
        ((DelegateCommand)SaveCommand).RaiseCanExecuteChanged();
        if (SubPO.Id == 0)
        {
            // Little trick to trigger the validation
            SubPO.Title = "";
        }
    }
}

SubInvoiceWrapper.cs(包装 DataGridView 中包含的内容)

public class SubInvoiceWrapper:ModelWrapper<SubInvoice>
{
    public SubInvoiceWrapper(SubInvoice model) : base(model)
    {
    }

    public string InvoiceName
    {
        get { return GetValue<string>(); }
        set { SetValue(value); }

    }
    public DateTime Date
    {
        get { return GetValue<DateTime>(); }
        set { SetValue(value); }

    }
    public decimal Amount
    {
        get { return GetValue<decimal>(); }
        set { SetValue(value); }

    }
    public List<string> Status
    {
        get { return GetValue<List<string>>(); }
        set { SetValue(value); }

    }
}

ViewModelBase.cs(包含已更改的属性)

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

}

运行程序的屏幕截图,如组合框所示为空!

标签: c#wpfmvvm

解决方案


推荐阅读