Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何解决异步数据调用上的空UI绑定?_C#_Wpf_Data Binding_Async Await_Task - Fatal编程技术网

C# 如何解决异步数据调用上的空UI绑定?

C# 如何解决异步数据调用上的空UI绑定?,c#,wpf,data-binding,async-await,task,C#,Wpf,Data Binding,Async Await,Task,我向IEnumerable集合添加了一个绑定,该集合由async方法调用填充。从远程数据库检索数据,然后将其添加到CustomerOrders列表中 但是在运行应用程序之后,我的UI绑定不会显示在视图上。该视图不显示任何数据 为了调试该问题,我检查了以下内容: 通过绑定到静态数据列表检查绑定和数据上下文 在数据调用后调试CustomerOrders列表,该列表在方法返回后显示为正在填充 我还检查了线程名称,它显示为一个。(不确定这是否是原因,因为这是另一个线程。) 3.1.我还在Customer

我向IEnumerable集合添加了一个绑定,该集合由
async
方法调用填充。从远程数据库检索数据,然后将其添加到
CustomerOrders
列表中

但是在运行应用程序之后,我的UI绑定不会显示在视图上。该视图不显示任何数据

为了调试该问题,我检查了以下内容:

  • 通过绑定到静态数据列表检查绑定和数据上下文

  • 在数据调用后调试CustomerOrders列表,该列表在方法返回后显示为正在填充

  • 我还检查了线程名称,它显示为一个。(不确定这是否是原因,因为这是另一个线程。) 3.1.我还在CustomerOrders属性上实现了本机INPC,并在
    set
    上设置了一个断点,显示列表已填充

  • 有人对这里可能出现的问题有什么建议吗

    CustomerOrderViewModel
    的摘要,设置如下。任务属性,
    初始化
    用于从构造函数调用初始化代码:

    using MongoDBApp.Models;
    using MongoDBApp.Services;
    using MongoDBApp.Utility;
    using PropertyChanged;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using MongoDBApp.Extensions;
    using System.Windows.Input;
    using MongoDBApp.Common;
    using MongoDBApp.Messages;
    
    namespace MongoDBApp.ViewModels
    {
        [ImplementPropertyChanged]
        public class CustomerOrdersViewModel : IPageViewModel, INotifyPropertyChanged
        {
    
            private IDataService<OrderModel> _orderDataService;
    
            public CustomerOrdersViewModel(IDataService<OrderModel> orderDataService)
            {
    
                _customerOrders = new List<OrderModel>();
                //{
    
                //    new OrderModel(){Email = "bvarley@gmail.com", Status = true}
                //};
    
    
                this._orderDataService = orderDataService;
                this._dialogService = dialogservice;
    
                Messenger.Default.Register<ProductModel>(this, OnUpdateProductMessageReceived);
    
                this.Initialization = InitializeAsync();
    
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
            }
    
            #region properties
    
            public string SelectedCustomerEmail { get; set; }
    
            private IEnumerable<OrderModel> _customerOrders; 
            public IEnumerable<OrderModel> CustomerOrders 
            { 
               get { return this._customerOrders;}
    
               set 
               {
                   _customerOrders = value;
                   OnPropertyChanged("CustomerOrders");           
               }
            }
    
            public OrderModel SelectedOrder { get; set; }
    
            public Task Initialization { get; set; }
    
            #endregion
    
            #region methods
    
            private async Task InitializeAsync()
            {
                var customer = await AwaitableMessages.NextMessageAsync<CustomerModel>(); 
                SelectedCustomerEmail = customer.Email;
                await LoadCustomerOrdersAsync(SelectedCustomerEmail);
            }
    
            public async Task LoadCustomerOrdersAsync(string email)
            {
                var ordersResult = await _orderDataService.GetAllByEmailAsync(email);
                CustomerOrders = ordersResult.ToObservableCollection();
            }
            #endregion
        }
    }
    
    使用mongodbap.Models;
    使用mongodbap.Services;
    使用mongodbap.Utility;
    使用改变的财产;
    使用制度;
    使用System.Collections.Generic;
    使用System.Collections.ObjectModel;
    使用系统组件模型;
    使用System.Linq;
    使用系统文本;
    使用System.Threading.Tasks;
    使用mongodbap.Extensions;
    使用System.Windows.Input;
    使用mongodbap.Common;
    使用mongodbap.Messages;
    名称空间mongodbap.ViewModels
    {
    [实现属性更改]
    公共类CustomerOrdersViewModel:IPageViewModel,INotifyPropertyChanged
    {
    私有IDataService_orderDataService;
    公共CustomerOrdersViewModel(IDataService orderDataService)
    {
    _customerOrders=新列表();
    //{
    //新建OrderModel(){Email=”bvarley@gmail.com“,Status=true}
    //};
    这是._orderDataService=orderDataService;
    这。_dialogService=dialogService;
    Messenger.Default.Register(这是OnUpdate ProductMessageReceived);
    this.Initialization=InitializeAsync();
    }
    公共事件属性更改事件处理程序属性更改;
    受保护的虚拟void OnPropertyChanged(字符串propertyName)
    {
    PropertyChangedEventHandler处理程序=PropertyChanged;
    if(handler!=null)handler(这是新的PropertyChangedEventArgs(propertyName));
    }
    #区域属性
    公共字符串SelectedCustomerEmail{get;set;}
    私人IEnumerable_客户订单;
    公共IEnumerable客户订单
    { 
    获取{返回此。\u customerOrders;}
    设置
    {
    _客户订单=价值;
    OnPropertyChanged(“客户订单”);
    }
    }
    public OrderModel SelectedOrder{get;set;}
    公共任务初始化{get;set;}
    #端区
    #区域方法
    专用异步任务InitializeAsync()
    {
    var customer=await AwaitableMessages.NextMessageAsync();
    SelectedCustomerEmail=customer.Email;
    等待加载CustomerOrdersAsync(已选择CustomerMail);
    }
    公共异步任务加载CustomerOrdersAsync(字符串电子邮件)
    {
    var ordersResult=await\u orderDataService.GetAllByEmailAsync(电子邮件);
    CustomerOrders=ordersResult.ToObservableCollection();
    }
    #端区
    }
    }
    
    这也是显示绑定设置的关联视图:

     <UserControl x:Class="MongoDBApp.Views.CustomerOrdersView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:boolean_converter="clr-namespace:MongoDBApp.Converters"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
             d:DesignHeight="300"
             d:DesignWidth="300"
             mc:Ignorable="d">
    
    <UserControl.Resources>
        <boolean_converter:BooleanConverter x:Key="BooleanConverter" />
    </UserControl.Resources>
    
    <Viewbox>
        <xctk:BusyIndicator IsBusy="{Binding ButtonEnabled}">
    
            <Grid>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="2*" />
                        <RowDefinition Height="1*" />
                        <RowDefinition Height="1*" />
                        <RowDefinition Height="1*" />
                        <RowDefinition Height="1*" />
                        <RowDefinition Height="1*" />
                        <RowDefinition Height="1*" />
                        <RowDefinition Height="1*" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="1*" />
                        <ColumnDefinition Width="1*" />
                        <ColumnDefinition Width="2*" />
                        <ColumnDefinition Width="1*" />
                        <ColumnDefinition Width="2*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
    
    
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Loaded">
                            <i:InvokeCommandAction Command="{Binding WindowLoadedCommand}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
    
                    <DataGrid x:Name="customersgrid"
                              Grid.Row="0"
                              Grid.RowSpan="3"
                              Grid.Column="1"
                              Grid.ColumnSpan="4"
                              AutoGenerateColumns="False"
                              ItemsSource="{Binding CustomerOrders}"
                              SelectedItem="{Binding SelectedOrder}">
                        <DataGrid.Columns>
                            <DataGridTextColumn Binding="{Binding Email}" Header="Email" />
                            <DataGridTextColumn Binding="{Binding Date}" Header="Date" />
                            <DataGridTextColumn Binding="{Binding Status}" Header="Shipping Status" />
                        </DataGrid.Columns>
                    </DataGrid>
                    <Label Grid.Row="4"
                           Grid.Column="1"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Top"
                           Content="Date:" />
    
    
                    <TextBlock Grid.Row="4"
                               Grid.Column="2"
                               HorizontalAlignment="Left"
                               VerticalAlignment="Top"
                               Text="{Binding SelectedOrder.Date}"
                               TextWrapping="Wrap" />
                    <Label Grid.Row="4"
                           Grid.Column="3"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Top"
                           Content="Products:" />
                    <ComboBox Grid.Row="4"
                              Grid.Column="4"
                              Grid.ColumnSpan="4"
                              Width="120"
                              HorizontalAlignment="Left"
                              VerticalAlignment="Top"
                              DisplayMemberPath="ProductId"
                              ItemsSource="{Binding SelectedOrder.Products}"
                              ScrollViewer.VerticalScrollBarVisibility="Visible"
                              SelectedItem="{Binding SelectedProduct}" />
                    <Label Grid.Row="5"
                           Grid.Column="1"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Top"
                           Content="Email:" />
    
    
                    <TextBlock Grid.Row="5"
                               Grid.Column="2"
                               HorizontalAlignment="Left"
                               VerticalAlignment="Top"
                               Text="{Binding SelectedOrder.Email}"
                               TextWrapping="Wrap" />
                    <RadioButton Grid.Row="5"
                                 Grid.Column="3"
                                 Grid.ColumnSpan="2"
                                 HorizontalAlignment="Left"
                                 VerticalAlignment="Top"
                                 Content="Shipped"
                                 IsChecked="{Binding SelectedOrder.Status,
                                                     Converter={StaticResource BooleanConverter},
                                                     ConverterParameter='true',
                                                     Mode=TwoWay}" />
    
                    <RadioButton Grid.Row="5"
                                 Grid.Column="4"
                                 Grid.ColumnSpan="2"
                                 HorizontalAlignment="Left"
                                 VerticalAlignment="Top"
                                 Content="Processing"
                                 IsChecked="{Binding SelectedOrder.Status,
                                                     Converter={StaticResource BooleanConverter},
                                                     ConverterParameter='false',
                                                     Mode=TwoWay}" />
                </Grid>
            </Grid>
        </xctk:BusyIndicator>
    </Viewbox>
    
    
    

    您的代码没有明显的错误;在我试图复制这个问题的过程中,我成功地做到了,没有任何问题。我在这里发布我的代码,希望能有所帮助

    我的订单模型类

    public class OrderModel
    {
        public string Email { get; set; }
        public DateTime Date { get; set; }
        public string Status { get; set; }
    }
    
    我的ViewModel(我使用了BaseViewModel;这是可选的。您所使用的方式还可以)


    我找到了一个解决方案,将异步调用放在窗口加载的任务中,而不是构造函数中

    解决方案:(消息处理程序首先注册传递的值,然后从窗口加载的任务调用异步加载方法)

    公共CustomerOrdersViewModel(IDataService orderDataService,IDialogService dialogservice) { 这是._orderDataService=orderDataService; 这。_dialogService=dialogService; Messenger.Default.Register(此,onUpdate-OrderMessageReceived); LoadCommands(); } 收到的更新OrderMessage上的私有无效(CustomerModel客户) { SelectedCustomerEmail=customer.Email; IsEnabled=true; } 专用异步任务WindowLoadedAsync(对象obj) { 等待加载CustomerOrdersAsync(已选择CustomerMail); }
    我尝试了上述方法,并将INPC代码添加到CustomerOrders属性中。但我的UI还是空白,有什么想法吗?您确定您的异步方法正在返回任何结果吗?您可以通过向
    set
    methodo添加断点来验证这一点
    public class MainWindowViewModel:BaseViewModel
    {
        public MainWindowViewModel()
        {
            _customerOrders = new List<OrderModel>();
            _customerOrders.Add(new OrderModel(){Date = DateTime.Now, Email = "mymail@gmail.com", Status = "Active"});
            InitializeAsync();
        }
    
        private List<OrderModel> _customerOrders;
        private OrderModel _selectedOrder;
    
        public List<OrderModel> CustomerOrders
        {
            get { return this._customerOrders; }
    
            set
            {
                _customerOrders = value;
                OnPropertyChanged("CustomerOrders");
            }
        }
    
        public OrderModel SelectedOrder
        {
            get { return _selectedOrder; }
            set
            {
                _selectedOrder = value;
                OnPropertyChanged("SelectedOrder");
            }
        }
    
        private async void InitializeAsync()
        {
            CustomerOrders = await LoadCustomerOrdersAsync();
        }
    
        private async Task<List<OrderModel>> LoadCustomerOrdersAsync()
        {
           return await Task.Run(() => new List<OrderModel>()
           {
               new OrderModel() {Date = DateTime.Now, Email = "mymail1@gmail.com", Status = "Active"},
               new OrderModel() {Date = DateTime.Now, Email = "mymail2@gmail.com", Status = "Active"},
               new OrderModel() {Date = DateTime.Now, Email = "mymail3@gmail.com", Status = "Active"},
               new OrderModel() {Date = DateTime.Now, Email = "mymail4@gmail.com", Status = "Active"},
               new OrderModel() {Date = DateTime.Now, Email = "mymail5@gmail.com", Status = "Active"},
               new OrderModel() {Date = DateTime.Now, Email = "mymail6@gmail.com", Status = "Active"},
           });
        }
    }
    
    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid HorizontalAlignment="Left" Margin="31,33,0,0" VerticalAlignment="Top" Height="250" Width="455" ItemsSource="{Binding Path=CustomerOrders, Mode=TwoWay}" SelectedItem="{Binding Path=SelectedOrder, Mode=TwoWay}">
            <!--<DataGrid.Columns>
                <DataGridCheckBoxColumn Binding="{x:Null}" ClipboardContentBinding="{x:Null}" Header="Email" HeaderStringFormat="Email"/>
                <DataGridCheckBoxColumn Binding="{x:Null}" ClipboardContentBinding="{x:Null}" Header="Date" HeaderStringFormat="Date"/>
                <DataGridCheckBoxColumn Binding="{x:Null}" ClipboardContentBinding="{x:Null}" Header="Status" HeaderStringFormat="Status"/>
            </DataGrid.Columns>-->
        </DataGrid>
    
    </Grid>
    
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
    }
    
        public CustomerOrdersViewModel(IDataService<OrderModel> orderDataService, IDialogService dialogservice)
        {                  
            this._orderDataService = orderDataService;
            this._dialogService = dialogservice;
    
            Messenger.Default.Register<CustomerModel>(this, OnUpdateOrderMessageReceived);
            LoadCommands();     
        }
    
        private void OnUpdateOrderMessageReceived(CustomerModel customer)
        {
            SelectedCustomerEmail = customer.Email;
            IsEnabled = true;                
        }
    
        private async Task WindowLoadedAsync(object obj)
        {
            await LoadCustomerOrdersAsync(SelectedCustomerEmail);
        }