Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.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# WPF MVVM绑定刷新以显示状态_C#_Wpf_Xaml_Mvvm - Fatal编程技术网

C# WPF MVVM绑定刷新以显示状态

C# WPF MVVM绑定刷新以显示状态,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我有一个“加载数据”过程,可能需要1到20秒,所以我想在我的窗口上显示一条状态消息。我的窗口网格有一行,该行将根据绑定到视图模型的触发器显示或隐藏。这很有效。我的问题是如何在长时间运行的任务开始之前更改绑定并刷新UI。现在发生的事情是,设置了Status属性,然后我启动了任务,但直到任务完成后,UI才会刷新。这是我的xaml和视图模型代码 <Grid Grid.Row="4" Background="{StaticResource appPrimaryBackColorLight}" He

我有一个“加载数据”过程,可能需要1到20秒,所以我想在我的窗口上显示一条状态消息。我的窗口网格有一行,该行将根据绑定到视图模型的触发器显示或隐藏。这很有效。我的问题是如何在长时间运行的任务开始之前更改绑定并刷新UI。现在发生的事情是,设置了Status属性,然后我启动了任务,但直到任务完成后,UI才会刷新。这是我的xaml和视图模型代码

<Grid Grid.Row="4" Background="{StaticResource appPrimaryBackColorLight}" Height="20">
    <Grid.Style>
        <Style TargetType="Grid">
            <Style.Triggers>
                <DataTrigger Binding="{Binding StatusMessageVisibility}" Value="Collapsed">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Height" From="20" To="0" Duration="0:0:0.1" />
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                    <DataTrigger.ExitActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Height" From="0" To="20" Duration="0:0:.1" />
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.ExitActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>
    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
        <Image Width="20" Height="20" Grid.RowSpan="2" ani:ImageBehavior.AnimatedSource="/Images/spinner_status_20.gif"></Image>
        <TextBlock Text="{Binding StatusMessage}" Height="20" VerticalAlignment="Center" Padding="5,1,0,0" Style="{StaticResource appTextBlockSmallDark}" Foreground="White" />
    </StackPanel>
</Grid>


private void LoadImportData() 
{
    // Show the status message by changing the view model properties
    StatusMessage = "Loading data from import file. Please stand by...";
    StatusMessageVisibility = Visibility.Visible;

    Task.Factory.StartNew(() =>
                          {
                              //This invokes UI specific code inside module initialization
                              LoadDataNow();
                          }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.FromCurrentSynchronizationContext());
}

私有void LoadImportData()
{
//通过更改视图模型属性显示状态消息
StatusMessage=“正在从导入文件加载数据。请待命…”;
StatusMessageVisibility=可见性。可见;
Task.Factory.StartNew(()=>
{
//这将在模块初始化中调用特定于UI的代码
LoadDataNow();
},CancellationToken.None,TaskCreationOptions.LongRunning,TaskScheduler.FromCurrentSynchronizationContext());
}

问题在于您正在使用当前同步上下文(即UI线程)执行任务。您没有在后台线程上运行它。相反,请使用worker任务的默认参数,将其安排在单独的线程上,并创建要在UI线程上运行的延续。任务完成后,此延续将更新UI

var task = Task.Factory.StartNew(() =>
                      {
                          //This invokes UI specific code inside module initialization
                          LoadDataNow();
                      });
task.ContinueWith(t => StatusMessageVisibility = Visibility.None, 
                       TaskScheduler.FromCurrentSynchronizationContext());

对于
StatusMessage
StatusMessageVisibility
,get+set是什么样子的<代码>INotifyPropertyChanged为这两个应用程序都实现了?是。。。我正在使用MVVM Light并为每个调用RaisePropertyChanged(),以便通知视图。我的LoadDataNow方法从文件中获取数据并将其加载到DevExpress GridControl中。不幸的是,即使我没有将这个网格放在窗口上,网格也需要在UI线程上运行,否则我会得到错误“调用线程必须是STA,因为许多UI组件都需要它。”我来自.NET 2.0世界,希望更好地理解和利用TPL。我知道我可以使用后台工作程序来运行它,但是使用任务看起来更干净。将所有数据加载到后台任务的内存中(这应该是长时间运行的位),然后将其绑定到延续中的网格控件。你不能也不应该将长时间运行的流程与UI代码混合在一起。谢谢Tim,但不幸的是,这不是一个选项,因为网格交互是我的长时间运行流程的一个组成部分。下面是我正在做的:(1)将一个大型excel工作簿加载到一个datatable中(2)将datatable分配给devexpress网格。(3) 针对网格中的数据运行大量文件管理器(DevExpress网格在高级过滤和性能之间表现突出,这就是我使用它的原因)。(4) 将剩余的过滤数据保存到我的数据库中。我必须同意@TimRogers的观点,你需要重新思考如何完成这项任务,UI代码不应该与流程紧密相关。我可以保证数据库过滤比datagrid过滤快,并且您可以直接从数据库中保存。感谢大家的输入,因为我能够找到一种方法来完成我想要的操作@JKing。。。当你不了解整个过程时,千万不要保证。当我只需要数据库中存储的50000条记录中的2000条记录时,您无法从excel加载50000条记录,并通过网络将其推送到VistaDB数据库,从而让数据库在网格中进行过滤与本地过滤。