我有一个简单的应用程序,在某些任务运行时显示进度环,并在任务完成后立即隐藏进度环。这段代码的问题是进度条永远不会折叠。
我在值转换器类中保留了一个断点,即使在值更改后它也不会收到 false 值。因此,ProgressRing 永远不会塌陷。我该如何解决这个问题?
这是我的视图模型:
public class TestVM : INotifyPropertyChanged
{
private bool _isRingVisible;
public bool IsRingVisible
{
get => _isRingVisible;
set
{
_isRingVisible = value;
OnPropertyChanged(nameof(IsRingVisible));
}
}
public TestVM()
{
Task.Run(async () => await DoSomething());
}
private async Task DoSomething()
{
IsRingVisible = true;
await Task.Delay(5000);
IsRingVisible = false; //Value set to false but when I have a break point in the value converter class, it never receives this value.
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
在 xaml 中,我有一个简单的 UI,如下所示,
<Page.Resources>
<converter:BoolToVisibilityConverter x:Key="boolToVisibility"/>
</Page.Resources>
<Grid>
<Border x:Name="BdrProgressRing"
Grid.Row="0"
Grid.RowSpan="2"
Background="Red"
VerticalAlignment="Center"
Opacity="0.6"
Visibility="{x:Bind vm.IsRingVisible,Mode=OneWay,Converter={StaticResource boolToVisibility}}">
</Border>
<ProgressRing x:Name="PgRing"
Grid.Row="0"
Grid.RowSpan="2"
Visibility="{Binding ElementName=BdrProgressRing, Path=Visibility}"
IsActive="True"
VerticalAlignment="Center"
Width="90"
Height="90"/>
</Grid>
这是我的xaml.cs
public sealed partial class MainPage : Page
{
public TestVM vm { get; set; }
public MainPage()
{
this.InitializeComponent();
vm = new TestVM();
this.DataContext = this;
}
}
改变
Task.Run(async () => await DoSomething()) ;
至
_ = DoSomething();
可能您只允许从主 UI 线程更改属性,而不是从池中
Task
。了解有关 WPF 中同步上下文的更多信息。
但是,以上是不好的做法。任何异步方法都应该等待。简单地将从
DoSomething()
返回的任务分配给局部变量是不够的。
由于您无法在构造函数中等待,因此视图模型应该有一个公共可等待方法,该方法实际上由调用者等待,例如
public TestVM()
{
}
public Task Initialize()
{
return DoSomething();
}
然后在视图中的异步 Loaded 事件处理程序中调用
await vm.Initialize();
:
public MainPage()
{
InitializeComponent();
vm = new TestVM();
DataContext = this;
Loaded += async (s, e) => await vm.Initialize();
}