Hi,
Need help trying to get my custom splash screen working based on this example from Channel 9 "Improving perceived WPF app startup performance with MEF and a Splash Screen".
I can't get any of the Storyboards to work nor display text in aTextBlock:
Creating the splash screen during InitializeModules() in my MefBootstrapper:
public class NatsarBootstrapper : MefBootstrapper { #region Private Properties private IEventAggregator EventAggregator { get { return ServiceLocator.Current.GetInstance<IEventAggregator>(); } } #endregion protected override void InitializeModules() { IModuleManager manager = ServiceLocator.Current.GetInstance<IModuleManager>(); Loading loading = this.Container.GetExportedValue<Loading>(); Shell shellMain = this.Container.GetExportedValue<Shell>(); loading.WindowStartupLocation = WindowStartupLocation.CenterScreen; loading.WindowState = WindowState.Normal; Application.Current.MainWindow = loading; Application.Current.MainWindow.Show(); EventAggregator.GetEvent<MessageUpdateEvent>().Publish(new MessageUpdateEvent { Message = "Loading TurahStudyUIModule" }); manager.LoadModule("TurahStudyUIModule"); Application.Current.MainWindow.Hide(); TurahStudyUIView view = ServiceLocator.Current.GetInstance<TurahStudyUIView>(); shellMain.Height = 768; shellMain.Width = 1024; shellMain.WindowStartupLocation = WindowStartupLocation.CenterScreen; shellMain.WindowState = WindowState.Maximized; shellMain.Activate(); Application.Current.MainWindow = shellMain; Application.Current.MainWindow.Content = view; Application.Current.MainWindow.Show(); } protected override void ConfigureAggregateCatalog() { try { this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(NatsarBootstrapper).Assembly)); this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(NatsarCommonModule).Assembly)); this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(TurahStudyUIModule).Assembly)); } catch (Exception msg) { ..... } } protected override DependencyObject CreateShell() { DependencyObject shell = null; return shell; } }
Loading.xaml Window:
<Window x:Class="NatsarTurahStudyMaster.Views.Loading" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" AllowsTransparency="True" WindowStyle="None" ><Window.Background><ImageBrush ImageSource="habakkuk-paleo-hebrew.png" Stretch="UniformToFill"/></Window.Background><Window.Resources><Storyboard x:Key="InTransition"><!-- Create an animation that repeats indefinitely. --><DoubleAnimation Storyboard.TargetName="foreverRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)" From="50" To="300" Duration="0:0:2" RepeatBehavior="Forever" /><!-- Create an animation that repeats for four seconds. As a result, the animation repeats twice. --><DoubleAnimation Storyboard.TargetName="fourSecondsRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)" From="50" To="300" Duration="0:0:2" RepeatBehavior="0:0:4" /><!-- Create an animation that repeats twice. --><DoubleAnimation Storyboard.TargetName="twiceRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)" From="50" To="300" Duration="0:0:2" RepeatBehavior="2x" /><!-- Create an animation that repeats 0.5 times. The resulting animation plays for one second, half of its Duration. It animates from 50 to 150. --><DoubleAnimation Storyboard.TargetName="halfRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)" From="50" To="300" Duration="0:0:2" RepeatBehavior="0.5x" /><!-- Create an animation that repeats for one second. The resulting animation plays for one second, half of its Duration. It animates from 50 to 150. --><DoubleAnimation Storyboard.TargetName="oneSecondRepeatingRectangle" Storyboard.TargetProperty="(Rectangle.Width)" From="50" To="300" Duration="0:0:2" RepeatBehavior="0:0:1" /></Storyboard></Window.Resources><Window.Triggers><EventTrigger RoutedEvent="FrameworkElement.Loaded"><BeginStoryboard Storyboard="{StaticResource InTransition}"/></EventTrigger></Window.Triggers><Grid><Border HorizontalAlignment="Stretch"><StackPanel Margin="20" ><TextBlock>RepeatBehavior="Forever"</TextBlock><Rectangle Name="foreverRepeatingRectangle" Fill="#AA3333FF" Width="50" Height="20" HorizontalAlignment="Left" /><TextBlock Margin="0,20,0,0">RepeatBehavior="0:0:4"</TextBlock><Rectangle Name="fourSecondsRepeatingRectangle" Fill="#AA3333FF" Width="50" Height="20" HorizontalAlignment="Left" /><TextBlock Margin="0,20,0,0">RepeatBehavior="2x"</TextBlock><Rectangle Name="twiceRepeatingRectangle" Fill="#AA3333FF" Width="50" Height="20" HorizontalAlignment="Left" /><TextBlock Margin="0,20,0,0">RepeatBehavior="0.5x"</TextBlock><Rectangle Name="halfRepeatingRectangle" Fill="#AA3333FF" Width="50" Height="20" HorizontalAlignment="Left" /><TextBlock Margin="0,20,0,0">RepeatBehavior="0:0:1"</TextBlock><Rectangle Name="oneSecondRepeatingRectangle" Fill="#AA3333FF" Width="50" Height="20" HorizontalAlignment="Left" /></StackPanel></Border><TextBlock Text="{Binding Status}" Margin="10,0" Grid.Row="2" Grid.ColumnSpan="2" TextAlignment="Right"><TextBlock.Effect><DropShadowEffect ShadowDepth="1" Color="#99ffffff"/></TextBlock.Effect></TextBlock></Grid></Window>
Loading.xaml.cs:
[Export(typeof(Loading))] [PartCreationPolicy(CreationPolicy.NonShared)] public partial class Loading : Window, IPartImportsSatisfiedNotification { public Loading() { InitializeComponent(); } [Import] public LoadingModel ViewModel { set { this.DataContext = value; } get { return DataContext as LoadingModel; } } /// <summary> /// Called when a part's imports have been satisfied and it is safe to use. /// </summary> public void OnImportsSatisfied() { // IPartImportsSatisfiedNotification is useful when you want to coordinate doing some work // with imported parts independent of when the UI is visible. Debug.WriteLine("Loading OnImportsSatisfied instantiation"); } }
LoadingModel.cs is where I'm just sending test text:
[Export(typeof(LoadingModel))] [PartCreationPolicy(CreationPolicy.NonShared)] public class LoadingModel : NotificationObject { [ImportingConstructor] public LoadingModel(IEventAggregator eventAggregator) { Debug.WriteLine("LoadingModel instantiation"); eventAggregator.GetEvent<MessageUpdateEvent>().Subscribe(e => UpdateMessage(e.Message)); } private string _status; public string Status { get { return _status; } set { _status = value; RaisePropertyChanged(() => this.Status); } } private void UpdateMessage(string message) { if (string.IsNullOrEmpty(message)) { return; } int maxRecords = 1000; for (int x = 1; x < maxRecords; x++) { System.Threading.Thread.Sleep(10); Status = string.Format("{0}: {1} {2}",message ,Convert.ToInt32( ((decimal)x / (decimal)maxRecords) * 100), "..."); } } }
But, nothing is working?
Code is like a box of chocolates!...