无法强制转换类型的对象

本文关键字:类型 对象 转换 | 更新日期: 2023-09-27 18:32:09

我在 wpf 应用程序中尝试将字符串从一个窗口发送到另一个窗口时出错:

无法将类型为"WpfApplication4.LoginWindow"的对象转换为类型"WpfApplication4.MainWindow"。

在我的登录窗口中,错误位于以下行:

((MainWindow)Application.Current.MainWindow).StudentID = UserAuthenticationID;

在我的主窗口中,我要测试以下内容:

    public string StudentId { get; set; }
    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        label1.Content = StudentID;
    }

我做错了什么?

编辑:

到目前为止,还没有答案有意义,这将是由于我晦涩的问题,我创建了一个 wpf 应用程序,我有两个窗口 MainWindow.xaml 和 LoginWindow.xaml。

我想在身份验证后将字符串(学生 ID)从登录窗口传递到主窗口。

我认为上面的方法是如何做到这一点,正如我所读的那样:((MainWindow)Application.Current.MainWindow).StudentID说我打算将字符串UserAuthenticationID发送到哪里?

然后在MainWindow.xaml我获取字符串UserAuthenticationID并设置它,然后我为这个公共字符串分配标签内容?

无法强制转换类型的对象

大概您从主窗口创建登录窗口。 如果您需要从登录窗口引用主窗口,请在构造登录窗口时将主窗口引用传递给登录窗口。 例如

void MainWindow_Loaded(object sender, RoutedEventArgs e) {
    LoginWindow login = new LoginWindow(this);
    login.ShowDialog();
}
class LoginWindow : Window {
    MainWindow app_window;
    public LoginWindow(MainWindow app_window) {
        Owner = app_window;
        this->app_window = app_window;
    }
}

错误来了,因为它试图将Application.Current.MainWindow转换为MainWindow,这实际上是LoginWindow

建议当你覆盖一个对象时,另一个在它之前做检查

if(Application.Current.MainWindow is MainWindow)
{
 /// than do the code 
}

看起来您试图将登录对话框中的 UserAuthenticationID 反馈回主窗口,在那里您将它存储为 StudentId。
为什么不在主窗口中处理它,例如:

if (login.ShowDialog())
    StudentId = login.UserAuthenticationID;

看起来您的 Application.Current.MainWindow 的类型是 LoginWindow。但是您希望将其强制转换为主窗口。两者都(也许)来自窗口。但是,不能将派生类强制转换为另一个派生类。

//编辑

尝试

((LoginWindow)Application.Current.MainWindow)

或将 Application.Current.MainWindow 更改为 MainWindow 类型的对象

编辑 2我想我明白你的意图是什么。您可以尝试以下操作:

在 LoginWindow 中,按下按钮"登录"处理按钮事件(单击),获取 ID 来自何处 (TextBox),将其放入 MainWindow 的新实例中并设置

Application.Current.MainWindow

到主窗口的新实例。如果我错了,你会怎么做,你应该提供更多的事实。

另一个解决方案是Ricibob的LoginDialog解决方案。

你需要重新组织程序的设计。 你想做的事情并不是非常困难;你本质上是在要求一种在表单之间进行交流的好方法。

首先,我建议不要使用Application.Current.MainWindow,除非你真的确定你需要这样做。 您可以使用它让应用程序工作,但它不是好的设计并导致问题。

我们将从一些将成为弹出窗口OtherWindow的定义开始。

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for OtherWindow.xaml
    /// </summary>
    public partial class OtherWindow : Window
    {
        public OtherWindow()
        {
            InitializeComponent();
        }
        public string SomeData
        {
            get
            {
                //you'll probably want to return the value of a textbox or something else 
                //the user fills in.
                return "Hello World!";
            }
        }
    }
}

从通信的角度来看,真正重要的是它有一个(或多个属性)属性,其中包含主窗体需要访问的信息。 显然,我省略了实际收集要返回的数据的所有代码,而是为此示例硬编码值。

现在是主窗体。 (我添加的只是一个按钮和一个标签。

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            OtherWindow other = new OtherWindow();
            other.Closed += (sender2, e2) =>
                {
                    label1.Content = other.SomeData;
                };
            //either of the methods below, depending on desired behavior.
            other.Show();
            //other.ShowDialog();
        }
    }
}

虽然有很多方法可以使不同的窗口/表单进行通信,但这是我最喜欢的。 窗口之间交互的所有逻辑都位于一个位置(按钮单击事件)。 主形态明明"拥有"OtherWindowOtheWindow不需要知道关于MainWindow的事情,只需要知道如何收集一些信息。 MainWindow将负责提取所需的信息。

按钮单击的代码甚至读起来就像您希望它执行的操作一样:创建一个新窗口,当它关闭时,将其内容设置为我的标签,然后显示表单。 它都在一个地方,并且按照我在逻辑上思考的顺序(如果需要,您可以在Show之后附加事件处理程序)。

哦,这与我在 winforms 应用程序中执行此操作的方式完全相同,以防有人关心,除非某些类/属性名称会有所不同。