【问题标题】:Unable to cast object of type无法转换类型的对象
【发布时间】:2012-04-25 16:21:36
【问题描述】:

在我的 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 并设置它,然后我将标签内容分配给这个公共字符串?

【问题讨论】:

  • 您的属性看起来很奇怪。为什么在其访问器中调用相同的属性名称?为什么要在 setter 中分配给 value 而不是相反?
  • 嗯...get 属性不会导致递归循环并最终导致堆栈溢出吗?
  • 我读它的方式是我试图从登录窗口“获取”StudentID,然后设置它的值?
  • 我认为我的第二个答案(“看起来像...”)为您提供了最明显/最标准的方式来做您想做的事。
  • 请修复您设置的属性,即:public string StudentId { get;放; }

标签: c# wpf


【解决方案1】:

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

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;
    }
}

【讨论】:

    【解决方案2】:

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

    当你隐藏一个对象时的建议,其他人在它之前检查过

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

    【讨论】:

      【解决方案3】:

      您似乎试图将登录对话框中的 UserAuthenticationID 提供回您将其存储为 StudentId 的主窗口。
      为什么不在主窗口中处理它例如:

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

      【讨论】:

      • 他没有说任何关于对话的事情。我认为他的 MainWindow 是从 Window 派生的 LoginWindow。
      • 她是的,你是对的,在 wpfapplication 我只是右键单击添加了新的 wpf 窗口。
      • ShowDialog 是 Window 的方法。对话框不会在 WPF 中退出 - 只有 Windows。请不要对您未获悉的内容投反对票。
      • 我没有投反对票。而且我并没有说您的解决方案不是针对 Window 作为对话框。但她对如何设计她的应用程序有另一个意图。因此,如果您尝试帮助一个明显的 wpf 新手,请以富有成效的方式提供帮助。特别是这个答案效率较低。对于拼写错误和语法错误,我很抱歉,这不是我的母语。
      • 我猜 Application.Current.MainWindow 不可能是一个对话框。但错误说,Application.Current.MainWindow 是一个登录窗口。因此,如果您尝试向她提出其他解决方案,请以有用的方式进行或顺其自然。
      【解决方案4】:

      您的 Application.Current.MainWindow 似乎属于 LoginWindow 类型。但是您想将其强制转换为 MainWindow。两者都(也许)从 Window 派生。但是您不能将派生类强制转换为另一个派生类。

      //编辑

      试试

      ((LoginWindow)Application.Current.MainWindow)
      

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

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

      在您按下按钮“登录”的登录窗口中,处理 Buttonevent(单击),从任何位置获取 ID(文本框),将其放入 MainWindow 的新实例中并设置

      Application.Current.MainWindow
      

      到 MainWindow 的新实例。如果我对你的做法有误,你应该提供更多的事实。

      其他解决方案是 Ricibob 的 LoginDialog 解决方案。

      【讨论】:

      • 它不存在,因为您将 StudentID 属性放在 MainWindow 类中。它是否存在于您的 LoginWindow 类中?
      • 那我应该如何在主窗口中引用 StudentID 呢?
      【解决方案5】:

      您需要重新构建程序的设计。你想做的事情并不难;您实际上是在寻求一种在表单之间进行交流的好方法。

      首先,我建议不要使用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();
              }
          }
      }
      

      虽然有很多方法可以使不同的窗口/表单进行通信,但这是我最喜欢的。窗口之间交互的所有逻辑都在一个地方(按钮单击事件)。主窗体显然“拥有”OtherWindow,而OtheWindow 不需要知道MainWindow 的任何事情,它只需要知道如何收集一些信息。 MainWindow 将负责提取所需的信息。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-09
        • 2017-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多