簡體   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