【问题标题】:Source of ElementName cannot be found in separate view在单独的视图中找不到 ElementName 的来源
【发布时间】:2012-12-05 11:13:49
【问题描述】:

我在 C# 中的 WPF 应用程序使用了 MVVM 模式。我定义了两个用户控件:

  • 登录查看
  • 项目视图

两个用户控件都添加到主窗口并使用相同的视图模型。 LoginView 包含一个PasswordBox,定义如下:

<PasswordBox Name="passwordBox" IsEnabled={Binding PasswordEnabled} />

ProjectsView 包含一个按钮,定义如下:

<Button Content="Login" Command="{Binding ProjectLoginCommand}" IsEnabled={Binding ProjectLoginEnabled}" CommandParameter="{Binding ElementName=passwordBox}" />

启动应用程序时,似乎无法绑定元素名称passwordBox。错误信息是:

Cannot find source for binding with reference 'ElementName=passwordBox' [...]

我该如何解决这个问题?

【问题讨论】:

  • 为什么需要 PasswordBox 控件作为 CommandParameter?
  • 点击按钮时我需要密码值(PasswordBox.Password)。但是,由于安全原因,无法直接绑定它。这就是为什么有几篇文章建议将完整的控件作为命令参数传递,然后访问 PasswordBox.Password。
  • 为什么不试试下面的代码:PasswordBox s = sender as PasswordBox; ViewModel.Password = s.Password;对于 PasswordBox_PasswordChanged 事件处理程序
  • 我只是想避免在代码隐藏中使用事件处理程序。
  • MVVM 严格地说 ViewViewModel 应该单独工作。您不应访问 ViewModel 中的 View 元素。

标签: wpf mvvm binding commandparameter


【解决方案1】:

你的元素

<PasswordBox Name="passwordBox" IsEnabled={Binding PasswordEnabled} />

位于LoginView用户控件,但按钮

<Button Content="Login" Command="{Binding ProjectLoginCommand}" IsEnabled={Binding ProjectLoginEnabled}" CommandParameter="{Binding ElementName=passwordBox}" />

位于ProjectsView。问题是您想从另一个用户控件的一个用户控件子元素访问。在我看来,将所有登录 UI 封装在 LoginView 用户控件中并将您的“项目” UI 封装在 ProjectsView 用户控件中应该是更好的解决方案。

【讨论】:

  • 这里的问题是我还需要ProjectsView的元素/命令中的PasswordBox中的密码。那么我也会有同样的问题,反之亦然:-)
  • 如果您对两个控件使用相同的 ViewModel,您可以在 ViewModel 中添加一些“密码”属性,在 LoginView 中设置此属性并通过 Binding 在 ProjectsView 中使用它。
  • 是的,这行得通。然而,这会违反一些安全问题,对吧?我现在创建了一个 PasswordBox 属性,但它看起来更像是一个肮脏的解决方法。实际上,微软应该对如何实现这样的事情有所了解?
  • 似乎MS根本不关心MVVM的任何支持,所以对我来说PasswordBox类型的属性是很好的安全解决方案,你可以使用它而不关心这样的小违规MVVM。还有另一种激进的解决方法:您可以创建一个合并视图,而不是 LoginView 和 ProjectsView。然后您可以像在第一个示例中一样将 PasswordBox 作为命令参数传递。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 2013-02-02
  • 2017-08-04
  • 1970-01-01
相关资源
最近更新 更多