首先是对我的应用的简短解释。我必须在每台PC上以8到16个屏幕呈现我的应用程序。在每个屏幕上是应用程序的另一部分。有些人正在无休止地重复播放视频,有些正在展示无休止的重复幻灯片,有些则具有更多功能。有些屏幕甚至是触摸屏,因此它也必须是交互式的。但是当我在一个线程上调用16个窗口时,你可以想象会发生什么...... 所以我使用以下选项: 在App.xaml.cs中,我使用foreach并浏览所有屏幕。每个屏幕都有一个xml文件中的配置,并使用screennumber和它应显示的内容进行调用。
但几乎在任何一开始它都会因为另一个错误消息而崩溃。我只能想到使用这种多GUI线程的内存错误。有时候我会得到未知的错误,有时候XML-Query会崩溃,有时它会成为IOStream,等等......
有人知道我能做得更好吗?我在哪里可以优化设置?或者我怎样才能显示多个带视频的窗口等等而不会相互冻结?
为了更好地理解我在做什么,我将代码粘贴到此处。
这是XAML:
<Window x:Class="ASA_Videowand.WheelOfFortune"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WheelOfFortune"
Name="WheelWindow"
WindowStyle="None"
Height="1080"
Width="1920"
Loaded="WheelOfFortune_OnLoaded">
<Window.Resources>
<Style x:Key="ImgZIndexStyle" TargetType="{x:Type Image}">
<Setter Property="Panel.ZIndex" Value="2"/>
<Style.Triggers>
<Trigger Property="Image.Opacity" Value="1">
<Setter Property="Panel.ZIndex" Value="3"/>
</Trigger>
</Style.Triggers>
</Style>
<Storyboard x:Key="FaderStoryboardHide1Show2">
<DoubleAnimation Storyboard.TargetName="FirstImage"
Storyboard.TargetProperty="Opacity"
To="0" Duration="0:00:01" />
<DoubleAnimation Storyboard.TargetName="SecondImage"
Storyboard.TargetProperty="Opacity"
To="1" Duration="0:00:01" />
</Storyboard>
<Storyboard x:Key="FaderStoryboardHide2Show1">
<DoubleAnimation Storyboard.TargetName="SecondImage"
Storyboard.TargetProperty="Opacity"
To="0" Duration="0:00:01" />
<DoubleAnimation Storyboard.TargetName="FirstImage"
Storyboard.TargetProperty="Opacity"
To="1" Duration="0:00:01" />
</Storyboard>
</Window.Resources>
<Grid>
<Grid Name="SlideShowGrid" ZIndex="0">
<Image x:Name="FirstImage" Stretch="UniformToFill" Style="{StaticResource ImgZIndexStyle}" Opacity="1" />
<Image x:Name="SecondImage" Stretch="UniformToFill" Style="{StaticResource ImgZIndexStyle}" Opacity="0"/>
</Grid>
<Canvas Name="VideoCanvas" ZIndex="0">
<Button Name="VideoButton" Click="VideoButton_OnClick">
<MediaElement Height="{Binding ElementName=WheelWindow, Path=Height}"
Width="{Binding ElementName=WheelWindow, Path=Width}"
UnloadedBehavior="Manual"
MediaEnded="MarketingVideoMediaElement_OnMediaEnded"
Name="MarketingVideoMediaElement" />
</Button>
</Canvas>
<Grid Name="WheelGrid" ZIndex="1">
<Button Name="SpinWheelButton" Click="SpinWheelButton_OnClick">
<Grid>
<Image Source="pics/gluecksrad_background.jpg" Stretch="UniformToFill" />
<Border>
<Border.Effect>
<DropShadowEffect Direction="330" Opacity="0.7" ShadowDepth="5" Color="Black" BlurRadius="3" RenderingBias="Performance" />
</Border.Effect>
<Image Name="ArrowImage" Source="pics/pfeil.png" Height="300" RenderTransformOrigin="0.5,0.5" Margin="414,330,1390,420">
<Image.RenderTransform>
<RotateTransform />
</Image.RenderTransform>
</Image>
</Border>
</Grid>
</Button>
</Grid>
</Grid>
WheelOfFortune.xaml.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using Microsoft.Win32;
using Panel = System.Windows.Controls.Panel;
namespace ASA_Videowand
{
public partial class WheelOfFortune
{
private int _listCounter;
private int _imageCounter;
private int _countTimer;
private int _screenNumber;
private List<string> _fileList;
private DoubleAnimation _rotateAnimation;
private readonly int _imageChangeTime;
private readonly string _myPath;
private readonly List<int> _targetAngelList = new List<int>();
private readonly DispatcherTimer _videoTimer = new DispatcherTimer();
private readonly DispatcherTimer _slideShowTimer = new DispatcherTimer();
private static readonly object MyLock = new object();
public WheelOfFortune(int screenNumber, string configName)
{
lock (MyLock)
{
InitializeComponent();
}
BuildList();
CreateVideoTimer();
_screenNumber = screenNumber;
var regKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
var openSubKey = regKey.OpenSubKey(@"SOFTWARE\ASA\Videowand", false);
if (openSubKey != null)
{
_myPath = openSubKey.GetValue("ProgramPath").ToString();
_imageChangeTime = Convert.ToInt32(openSubKey.GetValue("SlideShowTimer"));
}
GetDataFromHdd(configName);
}
private void GetDataFromHdd(string configName)
{
foreach (var fileList in from subDirectory in Directory.GetDirectories(_myPath, "*", SearchOption.AllDirectories)
where subDirectory.Contains(configName)
select Directory.GetFiles(subDirectory, "*", SearchOption.TopDirectoryOnly).ToList())
{
if (fileList[0].ToUpper().Contains(".JPG") || fileList[0].ToUpper().Contains(".GIF") ||
fileList[0].ToUpper().Contains(".JPEG") || fileList[0].ToUpper().Contains(".PNG") ||
fileList[0].ToUpper().Contains(".TIFF") || fileList[0].ToUpper().Contains(".BMP"))
{
_fileList = fileList;
BuildSlideShow();
}
else
ShowMovie(fileList[0]);
}
}
private void ShowMovie(string fileName)
{
CreateVideoStoryboard();
Panel.SetZIndex(VideoCanvas, 2);
MarketingVideoMediaElement.Source = new Uri(fileName);
}
private void BuildSlideShow()
{
Panel.SetZIndex(SlideShowGrid, 2);
WheelGrid.Opacity = 0;
FirstImage.Source = new BitmapImage(new Uri(_fileList[0]));
_slideShowTimer.Interval = new TimeSpan(0, 0, _imageChangeTime);
_slideShowTimer.Tick += Timer_Tick;
_slideShowTimer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
System.Windows.Controls.Image newImage;
Storyboard tempStoryboard;
if (FirstImage.Opacity == 1)
{
tempStoryboard = (Storyboard) FindResource("FaderStoryboardHide1Show2");
newImage = SecondImage;
}
else
{
tempStoryboard = (Storyboard)FindResource("FaderStoryboardHide2Show1");
newImage = FirstImage;
}
if (_imageCounter >= _fileList.Count - 1)
_imageCounter = 0;
else
_imageCounter++;
newImage.Source = new BitmapImage(new Uri(_fileList[_imageCounter]));
tempStoryboard.Begin();
}
private void CreateVideoTimer()
{
_videoTimer.Interval = TimeSpan.FromSeconds(1);
_videoTimer.Tick += VideoTimerOnTick;
}
private void VideoTimerOnTick(object sender, EventArgs eventArgs)
{
_countTimer++;
if (_countTimer <= 8) return;
Panel.SetZIndex(VideoCanvas, 2);
_videoTimer.Stop();
_countTimer = 0;
}
private void BuildList()
{
_targetAngelList.Add(11); // 1 Chip
_targetAngelList.Add(33); // 1 Chip
_targetAngelList.Add(56); // 1 Chip
_targetAngelList.Add(78); // 0 Chips
_targetAngelList.Add(101); // 2 Chips
_targetAngelList.Add(123); // 0 Chips
_targetAngelList.Add(146); // 1 Chip
_targetAngelList.Add(168); // 1 Chip
_targetAngelList.Add(191); // 1 Chip
_targetAngelList.Add(214); // 1 Chip
_targetAngelList.Add(237); // 1 Chip
_targetAngelList.Add(259); // 1 Chip
_targetAngelList.Add(281); // 0 Chips
_targetAngelList.Add(304); // 2 Chips
_targetAngelList.Add(327); // 0 Chips
_targetAngelList.Add(349); // 1 Chip
}
private void SpinWheelButton_OnClick(object sender, RoutedEventArgs e)
{
_countTimer = 0;
var targetAngel = new Random();
_listCounter = targetAngel.Next(0, _targetAngelList.Count - 1);
_rotateAnimation.To = 1800 + _targetAngelList[_listCounter];
((Storyboard)Resources["Storyboard"]).Begin();
}
private void CreateVideoStoryboard()
{
var spinningStoryboard = new Storyboard
{
Duration = new Duration(TimeSpan.FromMilliseconds(2500)),
};
_rotateAnimation = new DoubleAnimation
{
From = 0,
To = 1800 + _targetAngelList[_listCounter],
Duration = spinningStoryboard.Duration,
DecelerationRatio = 0.9
};
Storyboard.SetTarget(_rotateAnimation, ArrowImage);
Storyboard.SetTargetProperty(_rotateAnimation, new PropertyPath("(UIElement.RenderTransform).(RotateTransform.Angle)"));
spinningStoryboard.Children.Add(_rotateAnimation);
Resources.Add("Storyboard", spinningStoryboard);
}
private void VideoButton_OnClick(object sender, RoutedEventArgs e)
{
Panel.SetZIndex(VideoCanvas, 0);
_videoTimer.Start();
}
private void MarketingVideoMediaElement_OnMediaEnded(object sender, RoutedEventArgs e)
{
MarketingVideoMediaElement.Position = new TimeSpan(0, 0, 0, 0, 1);
MarketingVideoMediaElement.Play();
}
private void WheelOfFortune_OnLoaded(object sender, RoutedEventArgs e)
{
ShowOnMonitor();
}
private void ShowOnMonitor()
{
Screen[] screenArray = Screen.AllScreens;
if (_screenNumber >= screenArray.Length)
{
_screenNumber = 0;
}
Left = Convert.ToInt32(screenArray[_screenNumber].Bounds.Left);
Top = Convert.ToInt32(screenArray[_screenNumber].Bounds.Top);
WindowState = WindowState.Maximized;
}
}
}