XAML 为什么线程只运行一次-打开和关闭窗口?

xkftehaa  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(142)

我试图打开“加载”窗口,同时登录到程序.一切正常工作只有一次.第二次运行它,我得到错误:系统.InvalidOperationException:调用线程无法访问此对象,因为它属于另一个线程.请帮助.
ViewModel.cs

private ProszeCzekaj proszeCzekaj;

private async void ZalogujExecute(object obj)
{
    try
    {

        Thread tbr = new Thread(() =>
        {
            proszeCzekaj = new ProszeCzekaj();
            proszeCzekaj.Closed += (sender2, e2) =>
                proszeCzekaj.Dispatcher.InvokeShutdown();
            proszeCzekaj.Show();
            Dispatcher.Run();
        });
        tbr.SetApartmentState(ApartmentState.STA);  //required for WPF
        tbr.Start();

        var odp = await SprawdzLogowanie();
        if (odp==1)
        {
            
        }
        proszeCzekaj.Dispatcher.Invoke(proszeCzekaj.Window2Close);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

async Task<int> SprawdzLogowanie()
{
    await Task.Run(() =>
    {
        AplikacjaDbContext db = new AplikacjaDbContext();
        foreach (var user in db.UsersTable.ToList())
        {
            MessageBox.Show(user.userLogin); //for test
        }
    });
    
    return 1;
}

字符串
Logowanie.xaml.cs

namespace PGSQL.View
{
    /// <summary>
    /// Logika interakcji dla klasy Logowanie.xaml
    /// </summary>
    public delegate void dWindow2Close();
    public partial class Logowanie : Window
    {
        public Logowanie()
        {
            InitializeComponent();

            LogowanieViewModel model = new LogowanieViewModel();
            this.DataContext = model;
        }
    }
}


Loading.xaml.cs

namespace PGSQL.View
{
    /// <summary>
    /// Logika interakcji dla klasy ProszeCzekaj.xaml
    /// </summary>
    public partial class ProszeCzekaj : Window
    {
        public dWindow2Close Window2Close;

        public ProszeCzekaj()
        {
            InitializeComponent();
            Window2Close = new dWindow2Close(SecondWindowClose);

            IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
            var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
            var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
            DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));

            ProszeCzekajViewModel model = new ProszeCzekajViewModel();
            this.DataContext = model;
        }

        private void SecondWindowClose()
        {
            this.Close();
        }

        public enum DWMWINDOWATTRIBUTE
        {
            DWMWA_WINDOW_CORNER_PREFERENCE = 33
        }

        // The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
        // what value of the enum to set.
        // Copied from dwmapi.h
        public enum DWM_WINDOW_CORNER_PREFERENCE
        {
            DWMWCP_DEFAULT = 0,
            DWMWCP_DONOTROUND = 1,
            DWMWCP_ROUND = 2,
            DWMWCP_ROUNDSMALL = 3
        }

        // Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
        [DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
        internal static extern void DwmSetWindowAttribute(IntPtr hwnd,
                                                         DWMWINDOWATTRIBUTE attribute,
                                                         ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
                                                         uint cbAttribute);
    }
}

ygya80vv

ygya80vv1#

Show方法在重复使用时会掷回例外状况。
InvalidOperationException
Show()是在正在关闭(Closing)或已经关闭(Closed)的 windows 上呼叫。
如果你想重用一个窗口,它可能更好:

  • SecondWindowClose呼叫Hide,而不是Close
  • 为了防止用户关闭ProszeCzekaj,可以使用WindowStyle

相关问题