首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F# wpf异步命令完成状态

F# wpf异步命令完成状态
EN

Stack Overflow用户
提问于 2016-02-22 12:44:40
回答 3查看 321关注 0票数 2

我一直在实验使用F#视图模块的异步命令。问题是,当我单击按钮时,命令将被执行,但之后按钮将保持禁用状态。

Xaml:

代码语言:javascript
复制
<Button Content="start async worker" Command="{Binding StartAsyncCommand}" />

ViewModel:

代码语言:javascript
复制
type MainViewModel() as me = 
  inherit ViewModelBase()
//...
member __.StartAsyncCommand = me.Factory.CommandAsync(fun _ -> async { return () } )

我做错了什么?

编辑:

由于@FoggyFinder,我们确定问题实际上与App.fs文件有关:

代码语言:javascript
复制
open System
open FsXaml
open System.Windows

type MainWindow = XAML< "MainWindow.xaml">

[<STAThread>]
[<EntryPoint>]
let main argv = 
  Application().Run(MainWindow().Root)

创建基本为空的App.xaml并开始如下所示:

代码语言:javascript
复制
module main

open System
open FsXaml

type App = XAML<"App.xaml">

[<STAThread>]
[<EntryPoint>]
let main argv =
    App().Root.Run()

修好了。如果有人知道这件事的解释,请不要犹豫。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-24 19:44:18

我做错了什么?

问题是,在构造SynchronizationContext层时没有ViewModel,这意味着将事情推回UI上下文的内部代码不能正常工作。

在调用Application.Run()之前,您可以在入口点的开头添加以下内容来解决这一问题

代码语言:javascript
复制
if SynchronizationContext.Current = null then
    DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher)
    |> SynchronizationContext.SetSynchronizationContext

这将确保创建了Dispatcher并安装了一个有效的SynchronizationContext,并且很可能会为您修复这个问题。

票数 2
EN

Stack Overflow用户

发布于 2016-02-22 16:32:17

我使用了异步命令,但这个问题从未出现过。我试着复制你的代码-一切正常。你确定你给出了完整的代码吗?

尝试运行代码:.xaml:

代码语言:javascript
复制
<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>
<Grid>
    <Button Content="start async worker" Command="{Binding StartAsyncCommand}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5" />
    <TextBlock Text="{Binding Count}" Margin="5" HorizontalAlignment="Right"  VerticalAlignment="Top"></TextBlock>
</Grid>

ViewModel:

代码语言:javascript
复制
type MainViewModel() as me = 
    inherit ViewModelBase()    
    
    let count = me.Factory.Backing(<@ me.Count @>, 0)

    member __.StartAsyncCommand = me.Factory.CommandAsync(fun _ -> async { count.Value <- count.Value + 1 })
    member __.Count with get() = count.Value

关于…之间的区别

代码语言:javascript
复制
let dosomething _ = async { return () }
member __.StartAsyncCommand = me.Factory.CommandAsync(dosomething)

以及:

代码语言:javascript
复制
member __.StartAsyncCommand = me.Factory.CommandAsync(fun _ -> async { return () } )

看这个答案:https://chat.stackoverflow.com/transcript/message/26511092#26511092

票数 2
EN

Stack Overflow用户

发布于 2016-02-23 06:32:34

简单的解决办法是使用交互触发器:

代码语言:javascript
复制
<Button>
    <ia:Interaction.Triggers>
        <ia:EventTrigger EventName="Click">
            <fsx:EventToCommand Command="{Binding StartAsyncCommand}" />
        </ia:EventTrigger>
    </ia:Interaction.Triggers>
</Button>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35554054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档