internal async Task <bool> NavigateInternal <TResult>(IViewModel viewModel, Func <TResult, Task> callback1, Func <Task> callback2)
        {
            try
            {
                var viewModelType = viewModel.GetType();
                Tuple <Window, bool> windowInfo = null;

                // Check if the view model has a defined view
                var viewAttrib = viewModelType.GetCustomAttribute <ViewAttribute>(false);
                if (viewAttrib != null && viewAttrib.ViewType != null)
                {
                    // Create the view - use the activator, since we dont expect any code in the view
                    windowInfo = await this.CreateDefaultWindow(callback1, callback2, Factory.Create(viewAttrib.ViewType) as FrameworkElement, viewModel);
                }
                else if (viewAttrib != null && !string.IsNullOrEmpty(viewAttrib.ViewName))
                {
                    windowInfo = await this.CreateWindow(viewModel, callback1, callback2, viewAttrib.ViewName);
                }
                else // The viewmodel does not have a defined view... Maybe we have a data template instead
                     // If we dont have a dataTemplate... we try to find a matching FrameworkElement
                {
                    windowInfo = await this.CreateWindow(viewModel, callback1, callback2, viewModelType.Name);
                }

                var window = windowInfo.Item1;
                (viewModel as IDisposableObject).IsNotNull(x => x.Disposed += async(s, e) => await viewModel.Dispatcher.RunAsync(() => window.Close()));

                window.Closing += Window_Closing;
                window.Closed  += (s, e) => (viewModel as ICloseAwareViewModel).IsNotNull(x => x.Close());

                window.Activated += (s, e) =>
                {
                    // This only applies to windows that are not maximized
                    if (window.WindowState != WindowState.Maximized)
                    {
                        // Check if the window is visible for the user If the user has for example
                        // undocked his laptop (which means he lost a monitor) and the application
                        // was running on the secondary monitor, we can't just start the window with
                        // that configuration
                        if (!MonitorInfo.WindowIsInAnyMonitor(window.GetWindowHandle()))
                        {
                            var source        = PresentationSource.FromVisual(window);
                            var primaryBounds = MonitorInfo.PrimaryMonitorBounds;
                            window.Height = Math.Min(window.Height, primaryBounds.Height);
                            window.Width  = Math.Min(window.Width, primaryBounds.Width);

                            window.Left = Math.Max(0, (primaryBounds.Width / source.CompositionTarget.TransformToDevice.M11 / 2) - (window.Width / 2));
                            window.Top  = Math.Max(0, (primaryBounds.Height / source.CompositionTarget.TransformToDevice.M22 / 2) - (window.Height / 2));
                        }
                        else
                        {
                            // we have to make sure, that the title bar of the window is visible for
                            // the user
                            var monitorBounds = MonitorInfo.GetMonitorBounds(window.GetWindowHandle());

                            if (monitorBounds.HasValue)
                            {
                                window.Height = Math.Min(window.Height, monitorBounds.Value.Height);
                                window.Width  = Math.Min(window.Width, monitorBounds.Value.Width);
                                window.Left   = window.Left >= monitorBounds.Value.Left && window.Left <= monitorBounds.Value.Right ? window.Left : monitorBounds.Value.Left;
                                window.Top    = window.Top >= monitorBounds.Value.Top && window.Top <= monitorBounds.Value.Bottom ? window.Top : monitorBounds.Value.Top;
                            }
                            else // set the left and top to 0
                            {
                                window.Left = 0;
                                window.Top  = 0;
                            }
                        }
                    }
                };

                if (windowInfo.Item2)
                {
                    window.ShowDialog();
                }
                else
                {
                    window.Show();
                }

                return(true);
            }
            catch (XamlParseException)
            {
                throw;
            }
            catch (NullReferenceException)
            {
                throw;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return(false);
            }
        }
Exemple #2
0
        internal async Task <bool> NavigateInternal <TResult>(IViewModel viewModel, Func <TResult, Task> callback1, Func <Task> callback2)
        {
            try
            {
                var viewModelType = viewModel.GetType();
                Tuple <Window, bool> windowInfo;

                // Check if the view model has a defined view
                var viewAttrib = viewModelType.GetCustomAttribute <ViewAttribute>(false);
                if (viewAttrib != null)
                {
                    // Create the view - use the activator, since we dont expect any code in the view
                    windowInfo = await CreateDefaultWindow(callback1, callback2, Factory.Create(viewAttrib.ViewType) as FrameworkElement, viewModel);
                }
                else // The viewmodel does not have a defined view... Maybe we have a data template instead
                {
                    // we always prefer our selector, because it rocks
                    var templateSelector = Application.Current.Resources[typeof(CauldronTemplateSelector).Name] as DataTemplateSelector;
                    var dataTemplate     = templateSelector.SelectTemplate(viewModel, null);

                    // If we dont have a dataTemplate... we try to find a matching FrameworkElement
                    if (dataTemplate == null)
                    {
                        var possibleViewName = viewModelType.Name.Left(viewModelType.Name.Length - "Model".Length);
                        var possibleView     = Factory.Create(possibleViewName) ?? Factory.Create(Assemblies.GetTypeFromName(possibleViewName));

                        // On such case we create a dummy View
                        if (possibleView == null)
                        {
                            var textBlock = new TextBlock();
                            textBlock.Text         = viewModelType.FullName;
                            textBlock.Foreground   = new SolidColorBrush(Colors.Tomato);
                            textBlock.TextWrapping = TextWrapping.NoWrap;
                            textBlock.TextTrimming = TextTrimming.CharacterEllipsis;
                            textBlock.FontSize     = 18;

                            windowInfo = await CreateDefaultWindow(callback1, callback2, textBlock, viewModel);
                        }
                        else
                        {
                            windowInfo = await CreateDefaultWindow(callback1, callback2, possibleView as FrameworkElement, viewModel);
                        }
                    }
                    else
                    {
                        // try to get a WindowConfiguration attach in the datatemplate
                        windowInfo = await CreateDefaultWindow(callback1, callback2, dataTemplate.LoadContent() as FrameworkElement, viewModel);
                    }
                }

                var window = windowInfo.Item1;
                (viewModel as IDisposableObject).IsNotNull(x => x.Disposed += async(s, e) => await viewModel.Dispatcher.RunAsync(() => window.Close()));

                window.Closing += (s, e) =>
                {
                    var closeAware = viewModel as ICloseAwareViewModel;

                    if (closeAware != null)
                    {
                        e.Cancel = !closeAware.CanClose();
                    }
                };

                window.Closed += (s, e) => (viewModel as ICloseAwareViewModel).IsNotNull(x => x.Close());

                window.Activated += (s, e) =>
                {
                    // This only applies to windows that are not maximized
                    if (window.WindowState != WindowState.Maximized)
                    {
                        // Check if the window is visible for the user If the user has for example
                        // undocked his laptop (which means he lost a monitor) and the application
                        // was running on the secondary monitor, we can't just start the window with
                        // that configuration
                        if (!MonitorInfo.WindowIsInAnyMonitor(window.GetWindowHandle()))
                        {
                            var source        = PresentationSource.FromVisual(window);
                            var primaryBounds = MonitorInfo.PrimaryMonitorBounds;
                            window.Height = Math.Min(window.Height, primaryBounds.Height);
                            window.Width  = Math.Min(window.Width, primaryBounds.Width);

                            window.Left = Math.Max(0, (primaryBounds.Width / source.CompositionTarget.TransformToDevice.M11 / 2) - (window.Width / 2));
                            window.Top  = Math.Max(0, (primaryBounds.Height / source.CompositionTarget.TransformToDevice.M22 / 2) - (window.Height / 2));
                        }
                        else
                        {
                            // we have to make sure, that the title bar of the window is visible for
                            // the user
                            var monitorBounds = MonitorInfo.GetMonitorBounds(window.GetWindowHandle());

                            if (monitorBounds.HasValue)
                            {
                                window.Height = Math.Min(window.Height, monitorBounds.Value.Height);
                                window.Width  = Math.Min(window.Width, monitorBounds.Value.Width);
                                window.Left   = window.Left >= monitorBounds.Value.Left && window.Left <= monitorBounds.Value.Right ? window.Left : monitorBounds.Value.Left;
                                window.Top    = window.Top >= monitorBounds.Value.Top && window.Top <= monitorBounds.Value.Bottom ? window.Top : monitorBounds.Value.Top;
                            }
                            else // set the left and top to 0
                            {
                                window.Left = 0;
                                window.Top  = 0;
                            }
                        }
                    }
                };

                if (windowInfo.Item2)
                {
                    window.ShowDialog();
                }
                else
                {
                    window.Show();
                }

                return(true);
            }
            catch (XamlParseException)
            {
                throw;
            }
            catch (NullReferenceException)
            {
                throw;
            }
            catch (Exception e)
            {
                Output.WriteLineError(e.GetStackTrace());
                return(false);
            }
        }