【发布时间】:2015-06-25 21:16:17
【问题描述】:
我有一个基于 MVVM 的应用程序(不使用任何特定的 mvvm 库或框架),有几个按钮我想根据方法是否正在运行来启用和禁用。我在 ViewModel 上设置了一个 bool 属性“ProcessRunning”:
bool _ProcessRunning = false;
/// <summary>
/// Whether A Process Is Currently Taking Place
/// </summary>
public bool ProcessRunning
{
get
{
return _ProcessRunning;
}
set
{
if (_ProcessRunning != value)
{
_ProcessRunning = value;
RaisePropertyChanged("ProcessRunning");
}
}
}
然后我有一系列按钮,其样式将它们绑定到此属性,如下所示:
按钮:
<Button Name="btn_AddMore" Content="More" Style="{StaticResource ExecuteButtons}"
ToolTip="Enumerate Customer Folders To Get More Customer And Job Options"
Command="{Binding AddFolderOptions}"/>
风格:
<Style TargetType="Button" x:Key="ExecuteButtons">
<Setter Property="Width" Value="80"/>
<Setter Property="Height" Value="40"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="700"/>
<Setter Property="BorderBrush" Value="#FFA0A0A0"/>
<Setter Property="Margin" Value="12,0,0,0"/>
<Setter Property="Background" Value="#FFEEEEEE"/>
<Setter Property="IsEnabled" Value="{Binding ProcessRunning, Converter={StaticResource Inverse}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
除了我在执行其他操作的方法期间更改它之外,绑定按预期工作:
private void AddOptionsFromFolders(object Parameter)
{
try
{
ProcessRunning = true;
Transfer_Workers.Program.Processes.AddFolderChoices(ref _LocalSettings);
在这种情况下,视图直到 AddOptionsFromFolders 退出后才会更新。
我通过其他几个问题发现 UI 线程在此方法调用期间被阻塞,并且在方法完成之前不会被释放更新,所以我尝试了这个:
private void AddOptionsFromFolders(object Parameter)
{
try
{
ProcessRunning = true;
//Transfer_Workers.Program.Processes.AddFolderChoices(ref _LocalSettings);
Thread test = new Thread(() => { Thread.Sleep(2000); ProcessRunning = false; });
test.Start();
在这种情况下,当 ProcessRunning 设置为 true 时 UI 会更新,但当“测试”线程完成并应将 ProcessRunning 设置为 false 时,UI 不会更新。
我的 ViewModel 继承自主视图模型,以及从我声明了 RaisePropertyChanged 的基本视图模型继承:
internal void RaisePropertyChanged(string prop)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
我似乎无法弄清楚为什么当 ProcessUpdated 设置回 false 时 UI 不更新。没有抛出异常,并且输出窗口中没有警告或错误 (Visual Studio 2013 Pro)。
我的预期结果是,当方法运行时,按钮将被禁用,而不是按钮被启用。如果有人可以在这里阐明手头的问题,或者甚至提出一种不同的方式来通知 View 以更异步的方式更改的属性,我将不胜感激。
另外,如果有什么我不清楚或遗漏的信息,请直接询问,我会尽快给您。
【问题讨论】:
-
顺便说一句,Visual Studio 2013 Pro 是一个编辑器,不管你信不信,它对程序的输出没有直接影响;它只规定了可以使用的 .Net 版本。任何关于 SO 的帖子都更适合将正在编译的实际 .Net 版本放在标签列表中。
标签: c# wpf multithreading mvvm