【问题标题】:Populating a WPF ListBox based on a ComboBox Selection基于组合框选择填充 WPF 列表框
【发布时间】:2020-10-28 07:08:58
【问题描述】:

我正在尝试使用基于组合框选择的 SQL 存储过程中的数据填充 WPF 列表框。我已经让 ComboBox 按预期工作,但我无法让 ListBox 显示任何数据。我的命名可能有点奇怪,但可以将其想象为:ComboBox 从 SQL 获取所有食谱,而 ListBox 需要根据用户从该 ComboBox 中的选择显示成分列表及其数量。 API 和存储过程(...GetAll() 用于 ComboBox 和 GetByRationId() 用于 ListBox...)工作,因为我可以使用 API 中的 Swagger 检索正确的数据,并且可以填充 ComboBox 和 RationId TextBlock在 UI 中,但我无法让 ListBox 显示任何数据。我对编程还是新手,我正在学习教程等,我似乎找不到任何特别适合我的情况的东西。我猜我错过了一些东西。我添加了前面提到的 TextBlock 只是为了显示 RationId,这是从 SQL 获取正确数据所需要使用的,作为测试,只是为了确保 Id 正在通过......并且确实如此。

这是 Xaml...

    <StackPanel Grid.Column="1" Margin="50" Orientation="Vertical">
        <ComboBox x:Name="FeedGroup" MinWidth="300" MinHeight="50"
                  SelectedItem="{Binding SelectedFeedGroup}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding FeedGroupName}" />
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
        
        <TextBlock x:Name="SelectedFeedGroup_RationId" Height="81"/>

        <ListBox x:Name="FeedGroupRation" MinHeight="200" Padding="20" ItemsSource="{Binding SelectedFeedGroupRation}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Margin="10" HorizontalAlignment="Center">
                        <TextBlock Text="{Binding CommodityName}" FontSize="20" FontWeight="Bold"
                            VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        <TextBlock Text="{Binding CommodityPercentage}" FontSize="16" VerticalAlignment="Center"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox> 
    </StackPanel>

这里是 ViewModel 类...

public class FeedGroupPageViewModel : Screen
{

    IFeedGroupEndPoint _feedGroupEndPoint;
    IFeedGroupRationEndPoint _feedGroupRationEndPoint;
    IMapper _mapper;
    private readonly StatusInfoViewModel _status;
    private readonly IWindowManager _window;


    public FeedGroupPageViewModel(IFeedGroupEndPoint feedGroupEndPoint,
            IFeedGroupRationEndPoint feedGroupRationEndpoint,
            IConfigHelper configHelper,
            IMapper mapper,
            StatusInfoViewModel status,
            IWindowManager window)
    {
        _feedGroupEndPoint = feedGroupEndPoint;
        _feedGroupRationEndPoint = feedGroupRationEndpoint;
        _configHelper = configHelper;
        _mapper = mapper;
        _status = status;
        _window = window;
    }

    protected override async void OnViewLoaded(object view)
    {
        base.OnViewLoaded(view);
        try
        {
            await LoadFeedGroup();
        }
        catch (Exception ex)
        {

        }
    }

    private async Task LoadFeedGroup()
    {
        var FeedGroupList = await _feedGroupEndPoint.GetAll();
        var feedGroup = _mapper.Map<List<FeedGroupDisplayModel>>(FeedGroupList);
        FeedGroup = new BindableCollection<FeedGroupDisplayModel>(feedGroup);
    }

    private BindableCollection<FeedGroupDisplayModel> _feedGroup;
    public BindableCollection<FeedGroupDisplayModel> FeedGroup
    {
        get { return _feedGroup; }
        set
        {
            _feedGroup = value;
            NotifyOfPropertyChange(() => FeedGroup);
        }
    }

    private FeedGroupDisplayModel _selectedFeedGroup;
    public FeedGroupDisplayModel SelectedFeedGroup
    {
        get { return _selectedFeedGroup; }
        set
        {
            _selectedFeedGroup = value;
            NotifyOfPropertyChange(() => SelectedFeedGroup);
        }
    }



    private BindableCollection<FeedGroupRationModel> _feedGroupRation;
    public BindableCollection<FeedGroupRationModel> FeedGroupRation
    {
        get { return _feedGroupRation; }

        set
        {
            _feedGroupRation = value;
            NotifyOfPropertyChange(() => FeedGroupRation);
        }
    }

    private BindableCollection<FeedGroupRationModel> _selectedFeedGroupRation;
    public BindableCollection<FeedGroupRationModel> SelectedFeedGroupRation
    {
        get { return _selectedFeedGroupRation; }
        set
        {
            _selectedFeedGroupRation = value;
            NotifyOfPropertyChange(() => SelectedFeedGroupRation);
        }
    }
}

这里是模型类

public class FeedGroupDisplayModel : INotifyPropertyChanged
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public string FeedGroupName { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime LastModified { get; set; }
    public int RationId { get; set; }



    public event PropertyChangedEventHandler PropertyChanged;
    public void CallPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}


public class FeedGroupRationModel : INotifyPropertyChanged
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public int RationId { get; set; }
    public string RationName { get; set; }
    public int CommodityId { get; set; }
    public string CommodityName { get; set; }
    public int CommodityPercentage { get; set; }



    public event PropertyChangedEventHandler PropertyChanged;
    public void CallPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

这是我的端点类

public class FeedGroupEndPoint : IFeedGroupEndPoint
{
    private IAPIHelper _apiHelper;

    public FeedGroupEndPoint(IAPIHelper apiHelper)
    {
        _apiHelper = apiHelper;
    }

    public async Task<List<FeedGroupModel>> GetAll()
    {
        using (HttpResponseMessage response = await _apiHelper.ApiClient.GetAsync("/api/FeedGroup"))
        {
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsAsync<List<FeedGroupModel>>();
                return result;
            }
            else
            {
                throw new Exception(response.ReasonPhrase);
            }
        }
    }
}

public class FeedGroupRationEndPoint : IFeedGroupRationEndPoint
{
    private IAPIHelper _apiHelper;

    public FeedGroupRationEndPoint(IAPIHelper apiHelper)
    {
        _apiHelper = apiHelper;
    }
    public async Task<List<FeedGroupRationModel>> GetRationById()
    {
        using (HttpResponseMessage response = await _apiHelper.ApiClient.GetAsync("/api/FeedGroup"))
        {
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsAsync<List<FeedGroupRationModel>>();
                return result;
            }
            else
            {
                throw new Exception(response.ReasonPhrase);
            }
        }
    }
}

如果需要,我可以添加更多信息。我已经为此工作了很长一段时间,但我只是没有想法。任何帮助将不胜感激! 提前致谢!!

【问题讨论】:

  • 两件事。 1.我认为视图模型的SelectedFeedGroupRation属性应该是FeedGroupRationModel类型。 2. SelectedFeedGroup 更改后如何加载FeedGroupRation 集合?从您提供的代码中我看不到这一点。
  • @StevenB:您在哪里以及如何设置FeedGroupRation 属性?
  • 1) ComboBox.ItemsSource = ...的来源是什么? 2) 如果在您的类中声明了 INotifyPropertyChanged 接口,则所有属性必须是“只读”或通过此接口通知它们的更改。 3)据我了解,BindableCollection 实现了 INotifyCollectionChanged。如果是这样,那么最好将属性设置为“只读”。如果有必要,彻底改变集合,你需要清除它并用新元素填充它。
  • @EldHasp:我在我的问题的 xaml 代码中添加了一个ItemSource。我将它绑定到SelectedFeedGroupRation...虽然不确定这是否正确。不确定您在#3中的含义。我正在使用 TextBlocks 来尝试启动它,但我希望能够更改 ListBox 的返回值(在类似 TextBox 的东西中),然后将更新的值推送回服务器。
  • 如果我理解你的解释正确。您在 ComboBox 中选择所需的组。您在 SelectedFeedGroup 属性中有此组。最简单的方法是在set方法中添加SelectedFeedGroupf属性值变化时,调用SelectedFeedGroupRation属性中修改集合的方法。

标签: c# sql wpf xaml


【解决方案1】:

您似乎没有设置ListBox 绑定到某处的FeedGroupRation

我猜你想在设置SelectedFeedGroup 属性时获取项目并设置属性。然后,您可以将事件处理程序连接到 PropertyChanged 事件或覆盖 NotifyOfPropertyChange 方法。像这样的:

public override async void NotifyOfPropertyChange([CallerMemberName] string propertyName = null)
{
    base.NotifyOfPropertyChange(propertyName);
    if (propertyName == nameof(FeedGroup))
    {
        //get the items...
        var results = await ...;
        //set the source property
        FeedGroupRation = results;
    }

}

【讨论】:

  • 我已将我的 LoadFeedGroupRation() 方法添加到我的问题中的 ViewModel 类中。我已经尝试添加您的代码,等待说LoadFeedGroupRation() 方法,但我收到错误:“无法将 void 分配给隐式类型变量”。有什么想法吗?
  • LoadFeedGroupRation 方法的返回类型是什么?
  • LoadFeedGroupRation()方法需要返回FeedGroupRationModel的列表。
  • @StevenB:什么?这与您的问题有什么关系...?
【解决方案2】:

正如@Michal Davis 评论所说,我缺少一种加载口粮的方法,所以我添加了 LoadFeedGroupRation()...

    private async Task LoadFeedGroupRation()
    {
        var _feedGroupRation = await _feedGroupRationEndPoint.GetRation();
        var feedGroupRation = _mapper.Map<List<FeedGroupRationDisplayModel>> 
        (_feedGroupPenList);
        FeedGroupRationList = new BindableCollection<FeedGroupRationDisplayModel> 
        (feedGroupRation);
    }

还根据@EldHasp 的评论,我更新了 SelectedFeedGroup 设置器...

public FeedGroupDisplayModel SelectedFeedGroup
{
    get { return _selectedFeedGroup; }
    set
    {
        _selectedFeedGroup = value;
        var FeedGroupRation = LoadFeedGroup
        NotifyOfPropertyChange(() => SelectedFeedGroup);
    }
}

我不知道这是否是最好的方法,但我为我的情况工作。

【讨论】:

    猜你喜欢
    • 2023-01-14
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多