'System.Windows.Application' cannot run multiple times - wpf

This error ocurr when I call System.Application.Run(); in a WPF application. There is no other call to method Run(). Someone did see this?

Why would you need to call Run() manually? The framework does it for you if you have an Application derived object usually defined in a file called App.xaml.
If you go in your obj directory you'll find the auto generated file for the application object (file is called App.g.cs) and it has something similar to:
/// <summary>
/// App
/// </summary>
public partial class App : System.Windows.Application {
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent() {
#line 4 "..\..\App.xaml"
this.StartupUri = new System.Uri("Window1.xaml", System.UriKind.Relative);
#line default
#line hidden
}
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main() {
gridsh.App app = new gridsh.App();
app.InitializeComponent();
app.Run();
}
}
Notice it defines a static main which has the call to Run.

No, if you didn't include another call to Run, maybe try deleting the file and recreating it...

Related

Creating and running WPF window in another thread

So I am working on a console project which should display a WPF window at some point where I can see the visual representation of my graph while it continues running through the algorithm.
I've come so far that I can create a Window and open it in another thread, but as soon as I call Dispatcher.Run() the Console gets blocked. My approach so far:
Step 1: Creating a thread which creates the Application and an SynchronizationContext for itself once run
Step 2: Calling the application's method (it's an inherited custom class which provides these methods) to create a window using a transportation class, using the sync-context of the thread. Expectation: It should create an instance of a Window owned by the separate UI thread.
Step 3: Calling the ShowWindow() method on the application using the sync-context of the thread, which shows the Window (does work) and then runs the Dispatcher. Because it's dispatched using the sync-context of the thread, it shouldn't lock the Console thread. It does, though.
Step 4: Using the Window's dispatcher to call the update methods for the graph.
Well, in my thoughts this should perfectly well work, but somehow the Dispatcher locks the Console thread and not the UI thread. Am I overlooking something here?
The custom Application:
internal sealed class CrossThreadApplication : Application
{
private SynchronizationContext _context;
///=================================================================================================
/// <summary> Constructor. </summary>
///
/// <param name="context"> The context. </param>
///=================================================================================================
public CrossThreadApplication(SynchronizationContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
_context = context;
}
///=================================================================================================
/// <summary> Shows the window. </summary>
///
/// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are
/// null. </exception>
///
/// <param name="window"> The window. </param>
///=================================================================================================
public void ShowWindow(Window window)
{
if (window == null) throw new ArgumentNullException(nameof(window));
_context.Send(state =>
{
((Window)state).Show();
System.Windows.Threading.Dispatcher.Run();
}, window);
}
///=================================================================================================
/// <summary> Creates a new object. </summary>
///
/// <param name="handle"> The creation handle for a Window. </param>
///
/// <returns> An object. </returns>
///=================================================================================================
public void Create(CreationHandle<Window> handle)
{
_context.Send(state =>
{
CreationHandle<Window> hnd = (CreationHandle<Window>) state;
hnd.Set(Activator.CreateInstance(hnd.CreationType));
}, handle);
}
}
The UIHost class which hosts the UI thread and interacts with the application
static UIHost()
{
HostThread = new Thread(Start);
HostThread.SetApartmentState(ApartmentState.STA);
HostThread.Name = "UI Thread";
CreationEvent = new ManualResetEvent(false);
HostThread.Start(CreationEvent);
}
private static void Start(object o)
{
ManualResetEvent ev = (ManualResetEvent) o;
SynchronizationContext context = new SynchronizationContext();
SynchronizationContext.SetSynchronizationContext(context);
_application = new CrossThreadApplication(context);
ev.Set();
_application.Run();
}
///=================================================================================================
/// <summary> Executes the user interface operation. </summary>
///
/// <param name="windowType"> The window type. </param>
/// <param name="reset"> The reset. </param>
///
/// <returns> An object. </returns>
///=================================================================================================
internal static object RunUI(Type windowType, ManualResetEvent reset)
{
CreationEvent.WaitOne();
CreationHandle<Window> handle = new CreationHandle<Window>();
_application.Create(handle);
_application.ShowWindow(handle.Get());
reset.Set();
return handle.Get();
}
The issue occurs in CrossThreadApplication.ShowWindow() at *.Dispatcher.Run();.
Why is this so? How can I get this working? It has to be possible somehow.

How to unit test using a ViewModelLocator

I've created a custom view model locator using Autofac and set it up normally through the App.xaml like most of them are usually used. My problem is how do I unit test now? I'm getting an error every time I try to test a method that initializes a view
In my app.xaml:
<desktop:ViewModelLocator xmlns:local="clr-namespace:MyProject.Desktop" x:Key="ViewModelLocator" />
In each view:
DataContext="{Binding MyFirstViewModel, Source={StaticResource ViewModelLocator}}"
The Unit Test Error:
{"Cannot find resource named 'ViewModelLocator'. Resource names are case sensitive."}
I understand why cause when you unit test, there really isn't an instance of the actual App so what is a good way around this problem?
ViewModelLocator Code:
/// <summary>
/// Autofac object container
/// </summary>
private readonly IContainer objectContainer;
#region Constructor
/// <summary>
/// Constructor for view model locator
/// </summary>
public ViewModelLocator()
{
objectContainer = App.ObjectContainer;
//objectContainer.BeginLifetimeScope();
}
#endregion
#region Properties
/// <summary>
/// Gets the resolved instance of a main window view model
/// </summary>
public MainWindowViewModel MainWindowViewModel
{
get
{
return objectContainer.Resolve<MainWindowViewModel>();
}
}
public FirstViewModel MyFirstViewModel
{
get
{
return objectContainer.Resolve<FirstViewModel>();
}
}
public SecondViewModel MySecondViewModel
{
get
{
return objectContainer.Resolve<SecondViewModel>();
}
}
This is a bit late, but maybe useful. Instead of resolving objectContainer in the constructor, do it through the property:
//note this is a lazy getter, i.e. will be resolved when needed on the first call
private IContainer ObjectContainer
{
get
{
if(objectContainer == null)
objectContainer = App.ObjectContainer;
return objectContainer:
}
}
Then use the property through your code, not the field. Also when I am concerned about someone else using the field that I want to enforce through the property usage, I would rename it to something that would not easily be recognizable in the IntelliSence (zREgdnlksfObjectContainer for example:) ) Note the property is private, so nothing really changes. You can make the property internal and mark your lib to be visible to your unit test, so that in the unit test you can Mock it to WhenCalled() return/resolve IContainer.

WPF Best way of displaying a busy indicator when dynamically creating a page

I have a WPF application that runs as an XBAP in a browser. On a few pages all the controls are dynamically created depending on what the user selects. Because of this it can look like the application is not doing anything until all the controls are loaded. I'd like to have some sort of busy indicator displayed before hand to show the user that the controls are loading, it doesn't have to be animated although would be nice if it did. I've looked into the telerik busy indicator but this doesn't work as it's really for getting data for a single control and doesn't show until the controls are loaded which defeats the purpose.
I was thinking of displaying an overlay, or something similar, first, containing a loading logo, then load the page behind this and hide the overlay when the controls have loaded. I was wondering if this was the best way of going about this or if there's a better way?
Note: I haven't tried this in a XBAP browser app, but it works in WPF Apps without any problems!
I use a DispatcherTimer to show an hourglass when necessary, and abstract this code to a static class.
public static class UiServices
{
/// <summary>
/// A value indicating whether the UI is currently busy
/// </summary>
private static bool IsBusy;
/// <summary>
/// Sets the busystate as busy.
/// </summary>
public static void SetBusyState()
{
SetBusyState(true);
}
/// <summary>
/// Sets the busystate to busy or not busy.
/// </summary>
/// <param name="busy">if set to <c>true</c> the application is now busy.</param>
private static void SetBusyState(bool busy)
{
if (busy != IsBusy)
{
IsBusy = busy;
Mouse.OverrideCursor = busy ? Cursors.Wait : null;
if (IsBusy)
{
new DispatcherTimer(TimeSpan.FromSeconds(0), DispatcherPriority.ApplicationIdle, dispatcherTimer_Tick, Application.Current.Dispatcher);
}
}
}
/// <summary>
/// Handles the Tick event of the dispatcherTimer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private static void dispatcherTimer_Tick(object sender, EventArgs e)
{
var dispatcherTimer = sender as DispatcherTimer;
if (dispatcherTimer != null)
{
SetBusyState(false);
dispatcherTimer.Stop();
}
}
}
You would use it like this:
void DoSomething()
{
UiServices.SetBusyState();
// Do your thing
}
Hope this helps!

WPF ObservableCollection Thread Safety

I've got a MVVM setup.
My model periodically calls some service and then invokes an action on the ViewModel which then updates some variables exposed to the View.
The variable is an ReadOnlyObservableCollection<T>, which has an ObservableCollection<T> it listens on.
The problem is that the Model calls the callback from a different thread, and thus it doesn't allow me to clear the ObservableCollection<T> on a different thread.
So I thought: use the dispatcher, if we aren't on the correct thread, invoke it:
private void OnNewItems(IEnumerable<Slot> newItems)
{
if(!Dispatcher.CurrentDispatcher.CheckAccess())
{
Dispatcher.CurrentDispatcher.Invoke(new Action(() => this.OnNewItems(newItems)));
return;
}
this._internalQueue.Clear();
foreach (Slot newItem in newItems)
{
this._internalQueue.Add(newItem);
}
}
Code is pretty straightforward I think.
The problem is that, even though I execute it on the correct thread (I think) it still throws me an exception on the .Clear();
Why is this occuring? How can I work around it without creating my custom ObservableCollection<T>?
I typically initialize the dispatcher used by my view models in a common view model base to help ensure it is the UI thread dispatcher, as Will mentions.
#region ViewModelBase()
/// <summary>
/// Initializes a new instance of the <see cref="ViewModelBase"/> class.
/// </summary>
protected ViewModelBase()
{
_dispatcher = Dispatcher.CurrentDispatcher;
}
#endregion
#region Dispatcher
/// <summary>
/// Gets the dispatcher used by this view model to execute actions on the thread it is associated with.
/// </summary>
/// <value>
/// The <see cref="System.Windows.Threading.Dispatcher"/> used by this view model to
/// execute actions on the thread it is associated with.
/// The default value is the <see cref="System.Windows.Threading.Dispatcher.CurrentDispatcher"/>.
/// </value>
protected Dispatcher Dispatcher
{
get
{
return _dispatcher;
}
}
private readonly Dispatcher _dispatcher;
#endregion
#region Execute(Action action)
/// <summary>
/// Executes the specified <paramref name="action"/> synchronously on the thread
/// the <see cref="ViewModelBase"/> is associated with.
/// </summary>
/// <param name="action">The <see cref="Action"/> to execute.</param>
protected void Execute(Action action)
{
if (this.Dispatcher.CheckAccess())
{
action.Invoke();
}
else
{
this.Dispatcher.Invoke(DispatcherPriority.DataBind, action);
}
}
#endregion
You could then invoke an action on the view model dispatcher like this:
this.Execute(
() =>
{
this.OnNewItems(newItems);
}
);
A neat fix of this problem found on Codeproject- Multi-Threaded ObservableCollection and NotifyCollectionChanged Wrapper

XNA Folder Hierarchy

Ok so I'm new to XNA and I am just trying to get an image to show on the screen. I believe I have added the Images to the content folder in the VS2010 program HOWEVER when I try to run the program I get an error saying File not found. So I am wondering what folder to have the image in to just be able to call the image file Tank.png.
the code is simple:
namespace Aceldama_Windows_Game
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Vector2 mPosition = new Vector2(0, 0);
Texture2D mSpriteTexture;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
mSpriteTexture = this.Content.Load<Texture2D>("Tank");
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(mSpriteTexture, mPosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
What folder should I put the image into to be able to call the file directly without having to put the full file path? Essentially the problem being is it seems as though no matter where i place the tank.png file (whether it is in the the file with the executable/c# files or in the content folder)
The XNA Content Pipeline takes the items that are referenced by your content project and transforms them into XNB files. The ContentManager then loads those XNB files.
So the first thing to check is if the XNB files are being created where you expect them in your output directory.
According to the code you have posted, with Content.RootDirectory = "Content" and Content.Load<Texture2D>("Tank"), assuming a Windows Debug build, it will be looking for the file:
bin/x86/Debug/Content/Tank.xnb
If you changed the content project output directory, you need to change the RootDirectory you set in code as well.
So I figured out what the problem was after searching the web endlessly;p it The code was fine the problem was I needed to create a reference to the content folder in the project. uploaded a pic of the solution explorer to show what I needed to do!
Under Content References I did not have the "Aceldama_windows_gameContent" Added. That needs to be there to reference the game content folder with the images in it!

Resources