加载时 WPF 更新 UI
WPF Update UI while loading
我想在加载一些较长的工作时更新 UI。我想要的是在加载数据时我想显示一个 UserControl
,它只是一条等待消息。我尝试了 BackgroundWorker
、Dispatcher.BeginInvoke
和 ThreadPool.QueueUserWorkItem
,但我不知道为什么它没有按照预期进行。请帮忙
Dispatcher.BeginInvoke(new Action(() => img.Visibility = Visibility.Visible));
//Load some long wok here
Dispatcher.BeginInvoke(new Action(() => img.Visibility = Visibility.Collapsed), DispatcherPriority.Background);
我正在寻找的是在加载时显示图像,并且在加载完成时必须将其折叠。
编辑:
<Grid Grid.Column="2"
Name="DetailsPane">
<Grid.Background>
<ImageBrush ImageSource="img/back.jpg"
Stretch="UniformToFill" />
</Grid.Background>
<Image Name="img"
Margin="5"
Stretch="None"
Visibility="Collapsed"
Source="img/Loading.png" />
</Grid>
当列表框 SelectionChanged 正在加载时,我有一张图片要显示。因此,在 SelectionChanged 事件中,我将在名为 DetailsPane 的网格中加载详细信息,该信息是在 ListBox 上点击的特定内容。加载信息时 我应该如何在 DetailsPane 上显示此图像?
到这里
创建了一个名为 State 的 bool 类型的依赖项 属性,然后
.CS
private void LstAllFeatures_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
State = false;
// Loading Heavy Work
State = true;
}
XAML
<Image Name="img"
Margin="5"
Stretch="None">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Visibility"
Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding State}"
Value="False">
<Setter Property="Visibility"
Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
在 DeatilsPane.Children
-> _visualChildren
-> InternalArray[0]
中是一个图像。当在 WPF Visualizer 中打开时显示图像可见性 = 可见但它不显示。请点亮它。
添加一个bool
属性:
public bool IsLoading
{
get { return isLoading; }
set { isLoading = value; NotifyPropertyChanged("IsLoading"); }
}
数据绑定到 Image.Visibility
属性:
<Image Margin="5" Stretch="None" Source="img/Loading.png">
<Image .Style>
<Style>
<Setter Property="Control.Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoading}" Value="True">
<Setter Property="Control.Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
当您在后台线程上开始长时间的 运行ning 任务时将其设置为 true
:
IsLoading = true;
在漫长的 运行ning 过程完成后将其设置为 false
:
IsLoading = false;
请注意,这仅在您 运行 在后台线程上进行长 运行ning 进程时才有效,否则,UI 线程将忙而不更新。
第一个 userControl 必须像这样实现 INotifyPropertyChanged:
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
那么 State 必须像这样定义:
public bool _state;
public bool State
{
get { return _state; }
set
{
if (value != _state)
{
_state= value;
RaisePropertyChanged();
}
}
}
然后在您要调用 LongWork() 的代码中
State = true;
await Task.Run(()=>LongWork());
State = fasle;
然后在 xaml 你这样写:
<Image Margin="5"
Stretch="None">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Visibility"
Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding State,RelativeSource= {RelativeSource AncestorType={x:Type test:UserControlName}},Mode=TwoWay}"
Value="False">
<Setter Property="Visibility"
Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
我想在加载一些较长的工作时更新 UI。我想要的是在加载数据时我想显示一个 UserControl
,它只是一条等待消息。我尝试了 BackgroundWorker
、Dispatcher.BeginInvoke
和 ThreadPool.QueueUserWorkItem
,但我不知道为什么它没有按照预期进行。请帮忙
Dispatcher.BeginInvoke(new Action(() => img.Visibility = Visibility.Visible));
//Load some long wok here
Dispatcher.BeginInvoke(new Action(() => img.Visibility = Visibility.Collapsed), DispatcherPriority.Background);
我正在寻找的是在加载时显示图像,并且在加载完成时必须将其折叠。
编辑:
<Grid Grid.Column="2"
Name="DetailsPane">
<Grid.Background>
<ImageBrush ImageSource="img/back.jpg"
Stretch="UniformToFill" />
</Grid.Background>
<Image Name="img"
Margin="5"
Stretch="None"
Visibility="Collapsed"
Source="img/Loading.png" />
</Grid>
当列表框 SelectionChanged 正在加载时,我有一张图片要显示。因此,在 SelectionChanged 事件中,我将在名为 DetailsPane 的网格中加载详细信息,该信息是在 ListBox 上点击的特定内容。加载信息时 我应该如何在 DetailsPane 上显示此图像?
到这里
创建了一个名为 State 的 bool 类型的依赖项 属性,然后
.CS
private void LstAllFeatures_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
State = false;
// Loading Heavy Work
State = true;
}
XAML
<Image Name="img"
Margin="5"
Stretch="None">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Visibility"
Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding State}"
Value="False">
<Setter Property="Visibility"
Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
在 DeatilsPane.Children
-> _visualChildren
-> InternalArray[0]
中是一个图像。当在 WPF Visualizer 中打开时显示图像可见性 = 可见但它不显示。请点亮它。
添加一个bool
属性:
public bool IsLoading
{
get { return isLoading; }
set { isLoading = value; NotifyPropertyChanged("IsLoading"); }
}
数据绑定到 Image.Visibility
属性:
<Image Margin="5" Stretch="None" Source="img/Loading.png">
<Image .Style>
<Style>
<Setter Property="Control.Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoading}" Value="True">
<Setter Property="Control.Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
当您在后台线程上开始长时间的 运行ning 任务时将其设置为 true
:
IsLoading = true;
在漫长的 运行ning 过程完成后将其设置为 false
:
IsLoading = false;
请注意,这仅在您 运行 在后台线程上进行长 运行ning 进程时才有效,否则,UI 线程将忙而不更新。
第一个 userControl 必须像这样实现 INotifyPropertyChanged:
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
那么 State 必须像这样定义:
public bool _state;
public bool State
{
get { return _state; }
set
{
if (value != _state)
{
_state= value;
RaisePropertyChanged();
}
}
}
然后在您要调用 LongWork() 的代码中
State = true;
await Task.Run(()=>LongWork());
State = fasle;
然后在 xaml 你这样写:
<Image Margin="5"
Stretch="None">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Visibility"
Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding State,RelativeSource= {RelativeSource AncestorType={x:Type test:UserControlName}},Mode=TwoWay}"
Value="False">
<Setter Property="Visibility"
Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>