繁体   English   中英

C# 数据未出现在 ComboBox 尽管列表不为空

[英]C# Data doesn't appear in ComboBox although the list is not empty

一天中的好时光,我遇到了一个问题。 我有一个 ComboBox 从数据库输入数据。 我可以从数据库中获取数据,但由于某种原因,数据不想显示在 ComboBox 中。 我需要做什么才能显示数据? 先感谢您。

BoatView.xaml

<UserControl x:Class="OrderBoatNew.WPF.Controls.BoatCard"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:OrderBoatNew.WPF.Controls"
             xmlns:vm="clr-namespace:OrderBoatNew.WPF.ViewModels"
             mc:Ignorable="d"
             d:DesignHeight="400" d:DesignWidth="400">

    <UserControl.DataContext>
        <vm:BoatCardViewModel />
    </UserControl.DataContext>

    <Grid>
        <StackPanel Orientation="Horizontal">

            <Grid Margin="15 15 0 0">

                <Grid.Resources>
                    <Style TargetType="ComboBox">
                        <Setter Property="Margin"
                                Value="0 20 0 0" />
                    </Style>
                </Grid.Resources>

                <Grid.RowDefinitions>
                    <RowDefinition Height="auto" />
                    <RowDefinition Height="auto" />
                    <RowDefinition Height="auto" />
                </Grid.RowDefinitions>

                <TextBlock Text="Model:"
                           Grid.Row="0" />
                <ComboBox Grid.Row="0"
                          Width="150"
                          ItemsSource="{Binding Models}"
                          DisplayMemberPath="Name" />

                <TextBlock Text="Wood:"
                           Grid.Row="1" />
                <ComboBox Grid.Row="1"
                          ItemsSource="{Binding Woods}" />

                <TextBlock Text="Color:"
                           Grid.Row="2" />
                <ComboBox Grid.Row="2"
                          ItemsSource="{Binding Colors}" />
            </Grid>
        </StackPanel>
    </Grid>
</UserControl>

我试图同时取表并立即从表中取名称,但这些选项中没有一个不起作用。

BoatCardViewModel.cs

using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using OrderBoatNew.Domain.Models;
using OrderBoatNew.Domain.Services;
using OrderBoatNew.EntityFramework.Services;
using OrderBoatNew.EntityFramework;

namespace OrderBoatNew.WPF.ViewModels
{
    public class BoatViewModel : ViewModelBase
    {
        private readonly IDataService<Model> _modelService;
        private readonly IDataService<Wood> _woodService;
        private readonly IDataService<Color> _colorService;

        private List<Model> _models;

        public List<Model> Models
        {
            get => _models;
            set
            {
                _models = value;
                OnPropertyChanged(nameof(Models));
            }
        }
        
        private List<string> _woods;

        public List<string> Woods
        {
            get => _woods;
            set
            {
                _woods = value;
                OnPropertyChanged(nameof(Woods));
            }
        }

        private List<string> _colors;

        public List<string> Colors
        {
            get => _colors;
            set
            {
                _colors = value;
                OnPropertyChanged(nameof(Colors));
            }
        }

        public BoatViewModel()
        {
            var contextFactory = new OrderBoatNewDbContextFactory();
            _modelService = new GenericDataService<Model>(contextFactory);
            _woodService = new GenericDataService<Wood>(contextFactory);
            _colorService = new GenericDataService<Color>(contextFactory);
        }

        public static BoatViewModel LoadBoatViewModel()
        {
            BoatViewModel boatViewModel = new BoatViewModel();
            boatViewModel.LoadValues();

            return boatViewModel;
        }

        private async void LoadValues()
        {
            await _modelService.GetAll().ContinueWith(task =>
            {
                if (task.Exception == null)
                    Models = task.Result.ToList();
            });

            await _woodService.GetAll().ContinueWith(task =>
            {
                if (task.Exception == null)
                    Woods = task.Result.Select(w => w.Name).ToList();
            });

            await _colorService.GetAll().ContinueWith(task =>
            {
                if (task.Exception == null)
                    Colors = task.Result.Where(c => c.ForAdditionalMoney == false)
                                        .Select(c => c.Name)
                                        .ToList();
            });
        }
    }
}

IDataService.cs

using System.Collections.Generic;
using System.Threading.Tasks;

namespace OrderBoatNew.Domain.Services
{
    public interface IDataService<T>
    {
        Task<IEnumerable<T>> GetAll();
        Task<T> Get(int id);
        Task<T> Create(T entity);
        Task<T> Update(int id, T entity);
        Task<bool> Delete(int id);
    }
}

通用数据服务.cs

using System.Collections.Generic;
using System.Threading.Tasks;
using OrderBoatNew.Domain.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using OrderBoatNew.Domain.Models;

namespace OrderBoatNew.EntityFramework.Services
{
    public class GenericDataService<T> : IDataService<T> where T : DomainObject
    {
        private readonly OrderBoatNewDbContextFactory _contextFactory;

        public GenericDataService(OrderBoatNewDbContextFactory contextFactory) { _contextFactory = contextFactory; }

        public async Task<IEnumerable<T>> GetAll()
        {
            using (OrderBoatNewDbContext context = _contextFactory.CreateDbContext())
            {
                IEnumerable<T> entities = await context.Set<T>().ToListAsync();

                return entities;
            }
        }

        public async Task<T> Get(int id)
        {
            using (OrderBoatNewDbContext context = _contextFactory.CreateDbContext())
            {
                T entity = await context.Set<T>().FirstOrDefaultAsync((e) => e.ID == id);

                return entity;
            }
        }

        public async Task<T> Create(T entity)
        {
            using (OrderBoatNewDbContext context = _contextFactory.CreateDbContext())
            {
                EntityEntry<T> createdResult = await context.Set<T>().AddAsync(entity);
                await context.SaveChangesAsync();

                return createdResult.Entity;
            }
        }

        public async Task<T> Update(int id, T entity)
        {
            using (OrderBoatNewDbContext context = _contextFactory.CreateDbContext())
            {
                entity.ID = id;

                context.Set<T>().Update(entity);
                await context.SaveChangesAsync();

                return entity;
            }
        }

        public async Task<bool> Delete(int id)
        {
            using (OrderBoatNewDbContext context = _contextFactory.CreateDbContext())
            {
                T entity = await context.Set<T>().FirstOrDefaultAsync((e) => e.ID == id);
                context.Set<T>().Remove(entity);
                await context.SaveChangesAsync();

                return true;
            }
        }
    }
}

更新ViewModelCommand.cs

#nullable enable

using System;
using System.Windows.Input;
using OrderBoatNew.Domain.Models;
using OrderBoatNew.EntityFramework.Services;
using OrderBoatNew.WPF.Services;
using OrderBoatNew.WPF.State.Navigators;
using OrderBoatNew.WPF.ViewModels;

namespace OrderBoatNew.WPF.Commands
{
    public class UpdateViewModelCommand : ICommand
    {
        private readonly INavigator _navigator;

        public UpdateViewModelCommand(INavigator navigator)
        {
            _navigator = navigator;
        }

        public bool CanExecute(object? parameter)
        {
            return true;
        }

        public void Execute(object? parameter)
        {
            if (parameter is ViewType viewType)
            {
                _navigator.CurrentViewModel = viewType switch
                {
                    ViewType.Boats => BoatViewModel.LoadBoatViewModel(),
                    ViewType.BoatsAccessory => new BoatAccessoryViewModel(),
                    _ => throw new ArgumentOutOfRangeException()
                };
            }
        }

        public event EventHandler? CanExecuteChanged;
    }
}

首先,您将一个BoatCardViewModel实例分配为DataContext

<UserControl.DataContext>
   <vm:BoatCardViewModel />
</UserControl.DataContext>

你不应该这样做,这会破坏数据上下文 inheritance。 如果需要,您应该绑定实际使用用户控件的数据上下文属性,例如:

<BoatCard DataContext="{Binding ...}" />

现在,问题在于数据上下文视图 model 是使用无参数构造函数创建的,该构造函数初始化服务,但从不调用它们来获取数据。

另一个问题是LoadBoatViewModel方法要么根本没有被调用,要么没有用,因为调用会返回一个BoatCardViewModel实例,它从未在您的用户控件中设置。 因此,您可能正在使用视图 model 的两个不同实例,而没有注意到它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM