[英]F# wpf async command completion status
我一直在嘗試使用F#Viewmodule異步命令。 問題是當我單擊按鈕時,命令將被執行,但是此后按鈕保持禁用狀態。
XAML:
<Button Content="start async worker" Command="{Binding StartAsyncCommand}" />
視圖模型:
type MainViewModel() as me =
inherit ViewModelBase()
//...
member __.StartAsyncCommand = me.Factory.CommandAsync(fun _ -> async { return () } )
我究竟做錯了什么?
編輯:
感謝@FoggyFinder,我們確定問題實際上出在App.fs文件中:
open System
open FsXaml
open System.Windows
type MainWindow = XAML< "MainWindow.xaml">
[<STAThread>]
[<EntryPoint>]
let main argv =
Application().Run(MainWindow().Root)
創建基本上空的App.xaml並開始如下操作:
module main
open System
open FsXaml
type App = XAML<"App.xaml">
[<STAThread>]
[<EntryPoint>]
let main argv =
App().Root.Run()
修復。 如果有人知道這方面的解釋,請隨時提供。
我使用了異步命令,但從未出現此問題。 我試圖重現您的代碼-一切正常。 您確定輸入了完整的代碼嗎?
嘗試運行代碼:.xaml:
<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>
視圖模型:
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
關於之間的區別
let dosomething _ = async { return () }
member __.StartAsyncCommand = me.Factory.CommandAsync(dosomething)
和:
member __.StartAsyncCommand = me.Factory.CommandAsync(fun _ -> async { return () } )
看看這個答案: http : //chat.stackoverflow.com/transcript/message/26511092#26511092
我究竟做錯了什么?
問題在於,在構造ViewModel層時沒有適當的SynchronizationContext,這意味着將內容推回UI上下文的內部代碼無法正常工作。
您可以在調用Application.Run()
之前,在入口點的開頭添加以下內容來解決此問題:
if SynchronizationContext.Current = null then
DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher)
|> SynchronizationContext.SetSynchronizationContext
這將確保已創建Dispatcher
並安裝了有效的SynchronizationContext
,並且可能會為您解決問題。
一種簡單的解決方法是使用交互觸發器:
<Button>
<ia:Interaction.Triggers>
<ia:EventTrigger EventName="Click">
<fsx:EventToCommand Command="{Binding StartAsyncCommand}" />
</ia:EventTrigger>
</ia:Interaction.Triggers>
</Button>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.