在我的主类中,我创建了一个 wpf 窗口(p)和一个函数,用于在标签(内容)中显示带有给定消息的窗口。
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();
}
));
}
}
然后在另一个命名空间的另一个类中,我这样称呼它..
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 = "";
}
}
}
这仅在第一次时工作得很好,如果我用不同的消息再次调用它,它不会更新消息,但通知仍然有效,它只会显示旧消息。
我也有这个问题,改变MainWindow.p.Opacity
和MainWindow.p.Background
如果没有 Dispatcher.Invoke,我会收到错误消息“无法访问对象,因为不同的线程拥有它”。
如果我删除Commands.MyGlobals.inputtext = message;
并放在它Commans.MyGlobals.inputtext = "test1"
之前MainWindow.NotifProc("test1");
仍然不起作用。
我也尝试过创建这样的类:
public static class ExtensionMethods
{
private static Action EmptyDelegate = delegate () { };
public static void Refresh(this UIElement uiElement)
{
uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
}
}
并添加:
p.content.Refresh();
但没有运气。任何帮助都会很棒。:/
编辑
尽管它可能不是最好的,但我设法找到了解决方法:每次调用窗口动画时,我都会创建一个新窗口,而不是在开始时创建一个新窗口。VS 说线程必须是 STA,所以我在 STA 线程中调用它,最后我在窗口动画的末尾添加了一个检查,以便在第一个完成之前不能创建新窗口。
我的新 NotifProc 函数如下所示:
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();
}