- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
快速记录,这样我就不会浪费任何人的时间。从 nuget 安装 MVVMLight 时,我最终收到错误 null : The term 'null' is not recognized as the name of a cmdlet, function, script file, or operable program
。尽管如此,MVVMLight 似乎工作正常,但下面将描述的问题除外,但我想提一下以防万一。
我遇到命令执行完成后按钮未重新启用的问题。如果执行速度非常快,它们似乎有时会起作用,但任何需要一段时间的操作似乎都不起作用。这是竞争条件的尖叫声。
我正在使用 Task 来执行冗长的操作,以便 UI 可以更新。 Task 的第一步也是最后一步是适本地翻转 IsBusy(其中每个 CanExecute 方法 返回 !IsBusy;
)
我已经构建了一个简单的示例,它将使用 Thread.Sleep 来模拟缓慢的操作,它很好地展示了这个问题。 WaitOneSecondCommand
似乎间歇性地工作。 WaitTenSecondsCommand
和 WaitThirtySecondsCommand
从不工作。
不起作用 我的意思是按钮保持禁用状态,直到我点击表单上的某处。
我已经进行了大量研究,到目前为止我尝试过的解决方案都没有改变这种行为。我最终导致强制执行所有不同的“修复”以防我误解。
我尝试的一件事是扩展 RelayCommands 以引发属性更改。例如:
来自:
public RelayCommand WaitOneSecondCommand {
get; set;
}
收件人:
public RelayCommand WaitTenSecondsCommand {
get {
return _waitTenSecondsCommand;
}
set {
_waitTenSecondsCommand = value;
RaisePropertyChanged();
}
}
我没想到它会起作用,但我想尝试一下。我还尝试添加 WaitTenSecondsCommand.RaiseCanExecuteChanged();
我还尝试将 WaitTenSecondsCommand.RaiseCanExecuteChanged()
添加到 CommandExecute 方法,但这也没有改变任何东西。
private void WaitTenSecondsCommandExecute() {
Task.Run(() => {
IsBusy = true;
Thread.Sleep(10000);
IsBusy = false;
WaitTenSecondsCommand.RaiseCanExecuteChanged();
});
}
我还阅读了有关 CommandManager 的内容,因此我也添加了 CommandManager.InvalidateRequerySuggested()
。我将它添加到 IsBusy 中,认为这将是非常垃圾的,但我认为它会消除任何疑问
这又是竞争条件的味道,我在这里使用 Task,但这些任务不能同时运行,并且由于使用了 IsBusy 标志而不会相互冲突。
这是一个基本的 WPF 应用程序,使用 .Net 4.6.1 和从 Nuget 安装的 MVVMLight 5.2.0。
主窗口.xaml
<Window x:Class="StackOverflowExample.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" MinHeight="100" Width="150" ResizeMode="NoResize" SizeToContent="Height"
DataContext="{Binding Source={StaticResource Locator}, Path=Main}">
<StackPanel>
<Button Height="70" Margin="5" Command="{Binding WaitOneSecondCommand}">Wait 1 Second</Button>
<Button Height="70" Margin="5" Command="{Binding WaitTenSecondsCommand}">Wait 10 Seconds</Button>
<Button Height="70" Margin="5" Command="{Binding WaitThirtySecondsCommand}">Wait 30 Seconds</Button>
</StackPanel>
<Grid>
<Label HorizontalAlignment="Left" Width="84">IsBusy:</Label>
<TextBox IsReadOnly="True" HorizontalAlignment="Right" Width="45" Text="{Binding IsBusy}" Margin="4,5,5,5" />
</Grid>
</Window>
我已经添加了 IsBusy 的绑定(bind)以清楚地表明它正在正确更新。这也是了解 10 秒和 30 秒命令何时完成的唯一可靠方法。我不希望任何 MessageBoxes 强制您单击“确定”导致 CanExecute 更新。这是创可贴修复。
MainViewModel.cs
public class MainViewModel : ViewModelBase {
private bool _isBusy;
private RelayCommand _waitTenSecondsCommand;
public MainViewModel() {
WaitOneSecondCommand = new RelayCommand(WaitOneSecondCommandExecute, WaitOneSecondCommandCanExecute);
WaitTenSecondsCommand = new RelayCommand(WaitTenSecondsCommandExecute, WaitTenSecondsCommandCanExecute);
WaitThirtySecondsCommand = new RelayCommand(WaitThirtySecondsCommandExecute, WaitThirtySecondsCommandCanExecute);
}
public RelayCommand WaitOneSecondCommand {
get; set;
}
public RelayCommand WaitTenSecondsCommand {
get {
return _waitTenSecondsCommand;
}
set {
_waitTenSecondsCommand = value;
RaisePropertyChanged();
WaitTenSecondsCommand.RaiseCanExecuteChanged();
}
}
public RelayCommand WaitThirtySecondsCommand {
get; set;
}
public bool IsBusy {
get {
return _isBusy;
}
set {
_isBusy = value;
RaisePropertyChanged();
CommandManager.InvalidateRequerySuggested();
}
}
private void WaitOneSecondCommandExecute() {
Task.Run(() => {
IsBusy = true;
Thread.Sleep(1000);
IsBusy = false;
});
}
private void WaitTenSecondsCommandExecute() {
Task.Run(() => {
IsBusy = true;
Thread.Sleep(10000);
IsBusy = false;
WaitTenSecondsCommand.RaiseCanExecuteChanged();
});
}
private void WaitThirtySecondsCommandExecute() {
Task.Run(() => {
IsBusy = true;
Thread.Sleep(30000);
IsBusy = false;
});
}
private bool WaitOneSecondCommandCanExecute() {
return !IsBusy;
}
private bool WaitTenSecondsCommandCanExecute() {
return !IsBusy;
}
private bool WaitThirtySecondsCommandCanExecute() {
return !IsBusy;
}
}
请注意,在 View 模型中,我只在 WaitTenSeconds 上放置了一个支持字段以表明它不会改变行为。
最佳答案
这个问题完全归功于 Viv:https://stackoverflow.com/a/18385949/865868
我面临的问题是我在单独的线程中更新 IsBusy,而主 UI 线程显然依赖于它来更新按钮。
2020 年更新!
我想重新审视这个答案,因为我的理解是有缺陷的,尽管我觉得还有更好的方法。目标应该是不修改 IsBusy 的设置,或者根本不修改任何支持属性。此外,应避免使用 async void。
相应的 CommandExecute 方法现在只使用异步等待
private async Task WaitOneSecondCommandExecute() {
CanWaitOneSecond = true;
await Task.Delay(1000);
CanWaitOneSecond = false;
}
我对“CanWaitOneSecond”进行了此更改
public bool CanWaitOneSecond {
get => _canWaitOneSecond ;
set {
_canWaitOneSecond = value;
Set(() => CanWaitOneSecond , ref _canWaitOneSecond , value);
RaiseAllCanExecuteChanged();
}
}
public void RaiseAllCanExecuteChanged() {
foreach (var command in Commands) {
command.RaiseCanExecuteChanged();
}
}
public List<RelayCommand> Commands {
get;
}
我还对设置 RelayCommand 以支持 async Task 而不是 async void 的构造函数进行了细微更改
Commands = new List<RelayCommand>();
Commands.Add(WaitOneSecondCommand = new RelayCommand(async () => await WaitOneSecondCommandExecute(), WaitOneSecondCommandCanExecute));
我希望这可以节省人们大量的研究时间,如果此实现有任何问题,请告诉我。我还是希望把它清理干净
关于c# - MVVMLight CanExecute 在单击窗口之前无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35923686/
自从我 faced an issue由于背景图片对于不同分辨率的内容来说太短,我尝试将背景分成 3 部分并自动拉伸(stretch)中间部分以相应地填充顶部和底部图像之间的空间。不幸的是我没能在 CS
我从去年开始就在我的程序中运行这个函数(Linux 和 Windows)。 现在我需要实现一个新功能,我的新构建不再运行。 我还有其他使用 POST 的 CUrl 函数,结果是一样的:没问题,但我的
在评估函数应用方面,Haskell 是只支持普通降阶还是也支持应用降阶?我是否认为正常顺序是 Haskell 惰性的原因? 最佳答案 GHC 运行时不使用术语缩减策略,因为那会非常低效。事实上,GHC
怎么来的multi使用多处理池对多个“进程”上的数据进行分段和处理的函数比仅调用 map 慢(8 秒)。功能(6 秒)? from multiprocessing import Pool import
假设我正在渲染一个 3d GL_TRIANGLE。该对象需要 3 个顶点才能定义:A、B、C。我将此类数据放入缓冲区并通过 glVertexAttribPointer 将其绑定(bind)到着色器。
我有一个字体的三个文件,普通的,粗体的和浅色的。由于 font-weight:light 不存在,我该如何在 font-face 上设置 light 呢? 顺便问一下,font-weight:ligh
我是 C 的新手,我似乎无法弄清楚什么似乎是一个非常简单的指针问题。我的程序将行号添加到文件中。它逐行读入文件,然后在每行的开头添加一个行号。它在每个文件上都可以正常工作,如下所示: soccer@s
我有以下代码,我不确定为什么当它命中 Myclass 的析构函数时我会收到堆损坏检测错误。我相信我正在正确地释放内存?? #include #include using namespace std
有什么方法可以将“正常”数学符号解释为逆波兰符号 (RPN)..? 例如1) 2 + 3*4 - 1 = 234*+1-2) 5 (4-8) = 548- 你可以假设遵循 BODMAS 规则并且必须首
http://www.ergotopia.de/ergonomie-shop/ergonomische-kissen/orthopaedisches-sitzkissen的手机页面应该看起来像右边(检
我正在 Phonegap/Cordova 中构建一个应用程序。应用目前相当简单,但确实需要网络状态和地理定位插件才能工作。 到目前为止,我已经在 Android 上开发了该应用程序(目前它仅由一些基本
我一整天都在做这个,但没有运气 我设法在一行 TfidfVectorizer 中消除了问题 这是我的工作代码 from sklearn.feature_extraction.text import C
也许有人看到一个错误,问题是当我按btn2 (button 2)和btn3 (button 3)应用程序crashes时,但操作仍然有效,即video正在运行并且PDF打开,而button 1正常工作
我正在开发一个应用程序。它的第一页是登录屏幕。成功登录后,我想将用户带到选项卡式 Activity 。我怎样才能在安卓中做到这一点?谢谢 最佳答案 在 Android 中,启动 Activity 是通
我不确定我在这里做错了什么。 :normal! I### 当我对一个单词执行此命令时,我想要的最终结果是: ### word 但是我得到了这个: ###word 最佳答案 Vim 的 :normal是
我必须将 2 个静态矩阵发送到分配动态矩阵的函数,将矩阵 1 乘以矩阵 2,并返回新矩阵的地址。请注意,COMM 很常见。 我尝试删除 free_matrix 行,它工作正常。 void main()
我在我的一个项目中使用 Gnome libglib 并遇到了一个奇怪的错误。我可以输入 GList 的元素数量看起来仅限于 45 个。在第 45 个元素处,它给出了此错误 40 counter 41
我正在尝试获取“顶级”HWND 的尺寸。即,我想要 Firefox/Windows 资源管理器等的主 HWND 的当前尺寸。窗口。如果窗口最小化, GetWindowRect() 将不起作用。 Get
相同的标题:什么是索引 - 正常 - 全文 - 唯一? 最佳答案 普通索引用于通过仅包含行数据的切片或散列来加速操作。 全文索引向数据库的全文搜索 (FTS) 引擎指示它应该将数据存档在给定字段中,以
我正在使用 EnumParser来自 here它在 VC++ 中编译得很好,但是使用 gcc 我有这样的错误: ./Terminator.o: In function `EnumParser::Enu
我是一名优秀的程序员,十分优秀!