- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在以编程方式创建一些 UI,其中涉及一些繁重的处理。基本上我想要的是在我的 UI 正在构建/添加到窗口时运行加载器动画。添加的 UI 是一些网格和正在加载到其中的一些图像。
到目前为止,我已经尝试过 BackgroundWorker,但由于我需要使用 UI 线程来添加我正在构建的 UI,加载器将不会启动/动画,直到添加的 UI 完成。
我也尝试过一些异步方法但没有任何结果。我最后一次尝试是这样的,但它仍然需要访问 UI 线程,这最终会卡住 UI 动画,直到工作完成
private async void begin()
{
await this.LongRunOpAsync();
}
public Task LongRunOpAsync()
{
return Task.Run(() =>
{
InitGrid();
stopLoadingScreen();
});
}
我可能遗漏了一些东西,但我不知道是什么,而且我也没有办法做到这一点。任何帮助将不胜感激。
编辑:工作繁重的方法
private void makeIgrid()
{
Grid hostgrid = new Grid();
hostgrid.Name = "imagesHostGrid";
hostgrid.Width = 700;
hostgrid.VerticalAlignment = VerticalAlignment.Top;
hostgrid.HorizontalAlignment = HorizontalAlignment.Center;
hostgrid.SetValue(Canvas.ZIndexProperty, 0);
this.RegisterName(hostgrid.Name, hostgrid);
Grid imagegrid = new Grid();
imagegrid.Name = "imagegrid";
imagegrid.Height = height2;
//imagegrid.Width = 700;
imagegrid.SetValue(Canvas.ZIndexProperty, 0);
imagegrid.VerticalAlignment = VerticalAlignment.Top;
imagegrid.HorizontalAlignment = HorizontalAlignment.Center;
imagegrid.Margin = new Thickness(0, height1, 0, 0);//(left,top,right,bottom)
RowDefinition iRow1 = new RowDefinition();
iRow1.Height = new GridLength(2, GridUnitType.Star);
imagegrid.RowDefinitions.Add(iRow1);
RowDefinition iRow2 = new RowDefinition();
iRow2.Height = new GridLength(70, GridUnitType.Star);
imagegrid.RowDefinitions.Add(iRow2);
ScrollViewer sv = new ScrollViewer
{
CanContentScroll = true,
HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden,
VerticalScrollBarVisibility = ScrollBarVisibility.Disabled
};
for (int i = 0; i < images.Length; i++)
{
ColumnDefinition columns = new ColumnDefinition();
columns.MinWidth = 100;
columns.Width = new GridLength(100, GridUnitType.Star);
imagegrid.ColumnDefinitions.Add(columns);
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.UriSource = new Uri(currentDirectory + "//Media//Images//" + selectedFolder + "//" + System.IO.Path.GetFileName(images[i].ToString()), UriKind.Relative);
bmp.CacheOption = BitmapCacheOption.OnLoad;
Debug.WriteLine("Loading: " + currentDirectory + "//Media//Images//" + selectedFolder + "//" + System.IO.Path.GetFileName(images[i].ToString()));
bmp.EndInit();
Image img = new Image();
img.Name = System.IO.Path.GetFileNameWithoutExtension(images[i].ToString());
img.Source = bmp;
img.VerticalAlignment = VerticalAlignment.Center;
img.HorizontalAlignment = HorizontalAlignment.Center;
img.TouchDown += addImagetoScreen;
img.Width = 94;
img.Stretch = Stretch.Uniform;
img.SetValue(Canvas.ZIndexProperty, 0);
this.RegisterName(img.Name, img);
Border border = new Border();
border.SetResourceReference(Control.BackgroundProperty, "MenuSelected");
border.SetValue(Canvas.ZIndexProperty, 0);
Grid.SetRow(border, 0);
Grid.SetColumn(border, i);
Grid.SetRow(img, 1);
Grid.SetColumn(img, i);
imagegrid.Children.Add(border);
imagegrid.Children.Add(img);
}
sv.Content = imagegrid;
sv.SetValue(Canvas.ZIndexProperty, 0);
hostgrid.Children.Add(sv);
mainGrid.Children.Add(hostgrid);
}
最佳答案
好的。删除所有代码并重新开始。
这是你在 WPF 中的做法:
<Window x:Class="WpfApplication14.ItemsControlSample2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ItemsControlSample2" WindowState="Maximized">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="DarkGray" BorderBrush="Black" BorderThickness="1" CornerRadius="5"
Width="100" Height="100" Margin="10" >
<Grid>
<Image x:Name="img" Source="{Binding ImageSource}" Margin="2"/>
<TextBlock x:Name="txt" Text="Loading..." FontWeight="Bold"
VerticalAlignment="Center" HorizontalAlignment="Center"
Visibility="Collapsed" Foreground="AliceBlue"/>
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsLoading}" Value="True">
<Setter TargetName="img" Property="Source" Value="{x:Null}"/>
<Setter TargetName="txt" Property="Visibility" Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer>
<WrapPanel IsItemsHost="True"/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</Window>
代码隐藏:
public partial class ItemsControlSample2 : Window
{
public ItemsControlSample2()
{
InitializeComponent();
//Make sure you change this path to a valid path in your PC where you have JPG files
var path = @"F:\Media\Images\My Drums";
var images = Directory.GetFiles(path,"*.jpg")
.Select(x => new ImageViewModel()
{
Path = x,
});
DataContext = images.ToList();
}
}
数据项:
public class ImageViewModel : INotifyPropertyChanged
{
private bool _isLoading;
public bool IsLoading
{
get { return _isLoading; }
set
{
_isLoading = value;
OnPropertyChanged("IsLoading");
}
}
private ImageSource _imageSource;
public ImageSource ImageSource
{
get { return _imageSource; }
set
{
_imageSource = value;
OnPropertyChanged("ImageSource");
}
}
private string _path;
public string Path
{
get { return _path; }
set
{
_path = value;
OnPropertyChanged("Path");
LoadImageAsync();
}
}
private void LoadImageAsync()
{
IsLoading = true;
var UIScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
{
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.UriSource = new Uri(Path, UriKind.Relative);
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.EndInit();
bmp.Freeze();
return bmp;
}).ContinueWith(x =>
{
ImageSource = x.Result;
IsLoading = false;
},UIScheduler);
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
结果:
请注意我是如何在 XAML 中以声明方式定义 UI,而不是在 C# 代码中以程序方式创建它。这是一种更简洁的方法,因为它让 WPF 完成它的工作
我使用的是 ItemsControl
,它适用于 WPF 中所有基于“项目”的 UI。不管他们的外观如何。
另请注意我如何利用 DataBinding 用实际数据填充 UI,以及如何利用 DataTriggers
创建基本的有状态行为。
IsLoading == true
) 时,Image.Source
为空并显示 TextBlock
。IsLoading == false
) 时,Image.Source
将绑定(bind)到 ViewModel 数据,TextBlock
将被隐藏。看看我如何使用 WrapPanel
进行布局而不是手动放置项目。这为您提供了“类似资源管理器”的行为。尝试调整窗口大小以查看结果。
我强烈建议您阅读上面链接的文档,主要是关于 ItemsControl 的内容以及 Rachel 的 WPF Mentality 帖子。
WPF Rocks。只需将我的代码复制并粘贴到 File -> New Project -> WPF Application
中,然后亲自查看结果。
我使用的是 C# 4.0 和 .Net 4.0,所以我没有 async/await
。您应该能够删除所有基于 Task
的代码,并用这种更新、更清晰的异步方法替换它。
如果您需要进一步的帮助,请告诉我。
关于c# - WPF UI 多任务处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21002165/
希望是一个简单的问题,但我没有 iOS3/不支持设备多任务处理。 我的应用程序现在设置为在后台运行(播放音频),我有一个正在运行的动画,我通过 applicationDidEnterBackgroun
在 Android 中,我有一个带有设置菜单的屏幕,当加载屏幕时,我使用 ProgressDialog 显示消息“请等待。屏幕加载时”,直到搜索完成。 我想在搜索当前打开并且 ProgressDial
我想每 5 分钟拍一张照片,但应用程序必须在后台运行。出于完全合法的原因。 这可能吗? 我愿意去天涯海角去实现我的目标,如果一个公众不能实现这个目标,一个企业实体是否可以实现这个目标。 app设计有a
我正在以编程方式创建一些 UI,其中涉及一些繁重的处理。基本上我想要的是在我的 UI 正在构建/添加到窗口时运行加载器动画。添加的 UI 是一些网格和正在加载到其中的一些图像。 到目前为止,我已经尝试
我正在编写一个录制音频的应用程序。我正在研究在进行录音(在后台)时支持多任务处理的可行性。 从我目前所读的内容来看,答案似乎是否,特别是因为该程序旨在释放在关闭时正在使用的任何系统资源。 所以我想知道
在 PHP 中,我们通常在不考虑服务器功能的情况下进行编码。现在甚至 PC 也有多个内核并处理 64 位数据。据我所知,PHP 引擎本身经过优化以利用多核。我们程序员如何才能进一步优化代码以利用多核。
我正在尝试使用 iPhone OS 4.0 的多任务处理功能。我尝试在后台播放音频但没有成功。我在 info.plist 中添加了 UIBackgroundModes 属性,并提到需要在后台播放音频。
iOS 应用程序如何知道应用程序打开时屏幕上是否已经有键盘?应用程序运行后,它可以接收键盘显示/隐藏通知。但是,如果应用程序在分屏模式下作为辅助应用程序打开,而主应用程序已经显示键盘,则辅助应用程序不
当我的应用程序成为焦点应用程序时,它会收到 UIKeyboardDidShowNotification 和相关通知。但是,如果另一个应用程序专注于拆分的多任务 View ,它就不再接收它。我在模拟器中
我想知道 Lua 是否内置了抢占式多任务处理功能。我希望在我的多核系统上使用并发线程。 我研究了协程(参见 lua-users.org/wiki/CoroutinesTutorial 和 stacko
有没有办法选择加入 iOS 9 并排多任务而不选择滑入? 背景是我们的应用程序 UI 在并排模式下处理得很好,但在狭窄的滑过模式下根本无法正常工作。该应用程序主要是一个 PDF 注释器,因此从用户体验
我有一个带有 Adafruit Motor Shield 的 Arduino 作为我的机器人的一部分。我想在运行电机的同时在压电元件上播放音调。 问题是我不太清楚如何在我的代码中伪造/模拟多任务处理。
我想将 app 作为我在 ios 7 上的硕士论文,但我需要知道是否可以在后台运行相机。我需要在用户按下主页按钮后录制视频(当用户使用另一个应用程序时,它应该是汽车的交通摄像头,例如导航)。我知道这在
在我的应用程序中,我尝试获取新内容并使其保持最新,即使我的应用程序处于待机模式也是如此。为此,我想使用新的多任务处理 iOS 7 功能。 首先,我通过将 key fetch 添加到 Info.plis
在 iOS 4 中,当用户按下主页按钮时,正在运行的应用程序将保存当前状态并转到后台。但是我正在开发一个应用程序,我不希望它进入后台。我希望它自杀,就像在 iOS 3 及之前的版本中一样。我该怎么做?
我正在开发一个 iPhone 应用程序,它使用背景音频(无限循环)在应用程序进入后台后继续播放。 我的问题是我想实现一个“ sleep 定时器”,它会在指定时间后停止播放。 这可能吗?我花了一个小时寻
有谁知道在应用程序失去焦点(按下主页按钮时)后如何让音频流播放(从 AVPlayer 组件中的 webview 或)?在 iOS 4.2 中。我知道我必须阅读有关多任务处理的内容,但如果您能针对该特定
以前,如果一个人在自己的应用程序上显示一个键盘,那么他会将所有内容嵌入到 UIScrollView 中。并调整 contentInset以防止内容被键盘遮挡。 现在有了 iOS 9 上的 Split
我正在使用 Cordova 创建一个应用程序,我希望我的 iPad 应用程序能够使用这个名为“Split View”又名“Apps Side by Side”或“multitasking”的很酷的功能
我看过 WWDC 2010 关于采用多任务处理的讨论,并且我已经开始启用我们的应用程序,但是我对释放不可见 View 有疑问。 根据演讲(第 105 节 - 在 iPhone 操作系统上采用多任务处理
我是一名优秀的程序员,十分优秀!