简体   繁体   English

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

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

Good time of day, I ran into a problem.一天中的好时光,我遇到了一个问题。 I have a ComboBox to enter data from the database.我有一个 ComboBox 从数据库输入数据。 I can take data from the database, but for some reason the data doesn't want to be displayed in the ComboBox.我可以从数据库中获取数据,但由于某种原因,数据不想显示在 ComboBox 中。 What do I need to do to display the data?我需要做什么才能显示数据? Thank you in advance.先感谢您。

BoatView.xaml : 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>

I tried to take both the table and immediately take the Name from the table, but not one of these options doesn't work.我试图同时取表并立即从表中取名称,但这些选项中没有一个不起作用。

BoatCardViewModel.cs 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 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);
    }
}

GenericDataService.cs通用数据服务.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;
            }
        }
    }
}

UpdateViewModelCommand.cs更新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;
    }
}

First of all, you assign an instance of a BoatCardViewModel as DataContext .首先,您将一个BoatCardViewModel实例分配为DataContext

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

You should never do that, this breaks data context inheritance.你不应该这样做,这会破坏数据上下文 inheritance。 You should either bind the data context property where the user control is actually used if needed, eg:如果需要,您应该绑定实际使用用户控件的数据上下文属性,例如:

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

Now, the problem is that the data context view model is created using the parameterless constructor, which initializes the services, but never calls them to get the data.现在,问题在于数据上下文视图 model 是使用无参数构造函数创建的,该构造函数初始化服务,但从不调用它们来获取数据。

Another issue is that the LoadBoatViewModel method either does not get called at all or it is useless, as a call returns a new instance of a BoatCardViewModel which is never set in your user control.另一个问题是LoadBoatViewModel方法要么根本没有被调用,要么没有用,因为调用会返回一个BoatCardViewModel实例,它从未在您的用户控件中设置。 Therefore, you are potentially using two different instances of the view model, without noticing it.因此,您可能正在使用视图 model 的两个不同实例,而没有注意到它。

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

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