내 기본 클래스에서 wpf 창 (p) 및 레이블 (내용)에 주어진 메시지와 함께 창을 표시하는 함수를 만듭니다. 이 완벽하게 잘 작동WPF 창 별도 스레드에서 특정 기능을 업데이트하지 않습니다
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 = "";
}
}
}
나는 그런 것처럼 전화를 다른 네임 스페이스에있는 다른 클래스 다음
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();
}
));
}
}
..
처음에만, 나는 다른 메시지와 함께 다시 호출 경우 메시지를 업데이트하지는 않으나 notif는 여전히 작동하여 그냥 이전 메시지를 표시합니다.
나는 또한 내가 "다른 스레드가 그것을 소유하고 있기 때문에 개체에 액세스 할 수 없습니다"읽기 오류가 Dispatcher.Invoke없이 MainWindow.p.Opacity
및 MainWindow.p.Background
을 변경하여이 문제가 있었다.
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();
}
가능한 중복 https://stackoverflow.com/questions/661561/how-do-i-update-the-gui -from-another-thread-in-c) – MickyD
사람들은 항상 스레드를 한 번에 몇 초 동안 만 잠자기 상태로 만들 것을 항상 주장합니까? – MickyD
UI 스레드보다 여기에 관련된 다른 스레드가없는 것으로 보입니다. 'Dispatcher.Invoke'를 호출하면 새 스레드가 생성되지 않고 UI 스레드에서 대리자가 실행됩니다. 그러나 UI 스레드는 Thread.Sleep을 호출하여 차단됩니다. 대신'await Task.Delay (...)'를 사용하십시오. – Clemens