In my main class I create a wpf window (p) and a function to display the window with a given message on it in a label (content).
public partial class MainWindow : Window
{
    ///Creates Window
    public static Wils0n.Window1 p = new Wils0n.Window1();
    /// <summary>
    /// creates notif bar with message
    /// </summary>
    /// <param name="message">Message for notif bar</param>
    public static void NotifProc(string message)
    {
        ///sets global string to message
        Commands.MyGlobals.inputtext = message;
        p.Dispatcher.Invoke(new Action(delegate ()
        {
        MainWindow.p.Topmost = true;
        MainWindow.p.Top = 0;
        ///sets label content to global string (this only works once)
        MainWindow.p.content.Content = Commands.MyGlobals.inputtext;
        MainWindow.p.Left = System.Windows.SystemParameters.WorkArea.Width / 2 - (MainWindow.p.Width / 2);
        MainWindow.p.Show();
        Thread.Sleep(2000);
        while (MainWindow.p.Top != -114)
        {
            MainWindow.p.Top -= 3;
            Thread.Sleep(15);
        }
        MainWindow.p.Hide();
        }
        ));
    }
}
Then in another class in another namespace I call it like such..
namespace Wilson.Utils
{
    class Commands
    {
        public void start()
        {
             ///creates notification window thats reads "hello world"
             MainWindow.NotifProc("hello world");
             ///creates notification window thats reads "test1"
             ///For some reason reads "hello world"
             MainWindow.NotifProc("test1");
             ///creates notification window thats reads "test2"
             ///For some reason reads "hello world"
             MainWindow.NotifProc("test2");            
        }
        ///creates global string
        public static class MyGlobals
        {
            public static string inputtext = "";
        }
    }
}
This works perfectly fine the first time only, if I call it again it with a different message it wont update the message but the notif still works it just displays the old message.
I have also had this problem with changing MainWindow.p.Opacity and MainWindow.p.Background
Without Dispatcher.Invoke I get an error reading "cannot access object because a different thread owns it".
If I remove Commands.MyGlobals.inputtext = message; and put Commans.MyGlobals.inputtext = "test1" before MainWindow.NotifProc("test1"); it still doesn't work.
I have also tried creating a class like such:
public static class ExtensionMethods
{
    private static Action EmptyDelegate = delegate () { };
    public static void Refresh(this UIElement uiElement)
    {
        uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
    }
}
and adding:
p.content.Refresh();
but had no luck. Any help would be great. :/
EDIT
I managed to find a fix although it is probably not the best: instead of creating a new window at the beginning I create a new window each time the window animation is called. VS said the thread must be STA so I called it in an STA thread and lastly I added a check at the end of the window animation so that no new windows can be created until the first is done.
My new NotifProc function looks like this:
    public static void NotifProc(string message)
    {
        Tools.MyGlobals.notifmessage = message;
        var thread = new Thread(new ThreadStart(STAThread));
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        thread.Join();
    }
    private static void STAThread()
    {
        Wils0n.Window1 p = new Wils0n.Window1();
        p.content.Content = Tools.MyGlobals.notifmessage;
        p.content.Refresh();
        p.Topmost = true;
        p.Top = 0;
        p.Left = System.Windows.SystemParameters.WorkArea.Width / 2 - (p.Width / 2);
        p.Show();
        Thread.Sleep(2000);
        while (p.Top != -114)
        {
            p.Top -= 3;
            Thread.Sleep(15);
        }
        p.Close();
    }
 
    