我想做一些听起来非常简单的事情,但我觉得很难实现。
假设我有一些内容与慢速加载操作绑定。例如,一个可观察的列表,从本地SQL中检索并需要几秒钟。在发生这种情况时,我希望将内容展示器(例如Groupbox
)与"正在加载..."文字或任何其他“请等待”#39;内容类型。
我很快得出结论,在操作之前和之后简单地切换绑定到UI的布尔标志并不起作用。在整个操作完成之前,UI不会刷新。也许是因为操作是CPU密集型的,我不知道。
我现在正在研究Adorner
,但是我在“繁忙指标”的背景下搜索它的信息非常少。覆盖。从大约5年前开始,互联网上只有一些解决方案,我无法使用它们。
问题:
听起来很简单 - 如何在屏幕上暂时显示某些内容,而View Model正在努力更新绑定数据?
答案 0 :(得分:2)
我很快得出结论,在操作之前和之后简单地切换绑定到UI的布尔标志并不起作用。在整个操作完成之前,UI不会刷新。也许是因为操作是CPU密集型的,我不知道。
是的,如果您实际在后台线程上执行长时间运行的操作,它应该可以工作。
请参阅以下简单示例。
查看:强>
<Window x:Class="WpfApplication2.Window1"
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"
xmlns:local="clr-namespace:WpfApplication2"
mc:Ignorable="d"
xmlns:s="clr-namespace:System;assembly=mscorlib"
Title="Window1" Height="300" Width="300">
<Window.DataContext>
<local:Window1ViewModel />
</Window.DataContext>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
<TextBlock>Content...</TextBlock>
<Grid Background="Yellow" Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Loading...</TextBlock>
</Grid>
</Grid>
</Window>
查看型号:
public class Window1ViewModel : INotifyPropertyChanged
{
public Window1ViewModel()
{
IsLoading = true;
//call the long running method on a background thread...
Task.Run(() => LongRunningMethod())
.ContinueWith(task =>
{
//and set the IsLoading property back to false back on the UI thread once the task has finished
IsLoading = false;
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
public void LongRunningMethod()
{
System.Threading.Thread.Sleep(5000);
}
private bool _isLoading;
public bool IsLoading
{
get { return _isLoading; }
set { _isLoading = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
答案 1 :(得分:1)
以下是在ViewModel \ Model处理某项长任务时如何使用“正在加载”显示设置视图的示例。
<强>窗口强>
div.panel:hover {
border: 1px solid grey;
/*I want the panel-heading to be grey*/
}
.panel-default > .panel-heading {
background-color: #16749F;
color: #ddd;
}
.panel-default > .panel-heading:hover {
background-color: grey;
}
VisibilityConverter.cs (简单助手转换器)
<Window x:Class="Loading.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"
xmlns:local="clr-namespace:Loading"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:VisibilityConverter x:Key="visibilityConverter" />
</Window.Resources>
<Window.DataContext>
<local:ViewModel x:Name="viewModel" />
</Window.DataContext>
<Grid>
<Button Content="Perform" VerticalAlignment="Bottom" HorizontalAlignment="Center" Width="100" Height="30" Command="{Binding HandleRequestCommand}" />
<Border Visibility="{Binding Path=IsLoading,Converter={StaticResource visibilityConverter}}" Background="#AAAAAAAA" Margin="5">
<TextBlock Text="Loading..." VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
</Grid>
<强> ViewModel.cs 强>
class VisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}