0

My WPF application in C# makes use of the MVVM pattern. There are two user controls I have defined:

  • LoginView
  • ProjectsView

Both user controls are added to a main window and make use of the same view model. The LoginView contains a PasswordBox defined as follows:

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

The ProjectsView contains a button defined as follows:

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

When starting the application it seems as if the element name passwordBox cannot be bound. The error message is:

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

How can I fix this?

Robert Strauch
  • 12,055
  • 24
  • 120
  • 192
  • why you need a PasswordBox control as your CommandParameter? – niao Dec 05 '12 at 11:19
  • I need the password value (PasswordBox.Password) when clicking the button. However it is not possible to directly bind this due to security reasons. That's why several articles propose to pass the complete control as a command parameter and then access PasswordBox.Password. – Robert Strauch Dec 05 '12 at 11:21
  • Why don't you try the following code:PasswordBox s = sender as PasswordBox; ViewModel.Password = s.Password; for PasswordBox_PasswordChanged event handler – niao Dec 05 '12 at 11:25
  • I'd just like to avoid event handlers in the code-behind. – Robert Strauch Dec 05 '12 at 11:33
  • `MVVM` strictly says `View` and `ViewModel` should work in isolation. You should not access View element in your ViewModel. – Rohit Vats Dec 05 '12 at 11:44
  • Try to use x:Name="passwordBox" instead of Name="passwordBox". – EugenSoft Dec 05 '12 at 12:42
  • @RV1987 - where in my suggested code ViewModel knows about View anything? – niao Dec 05 '12 at 13:22

1 Answers1

1

Your element

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

located in LoginView user control, but button

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

located in ProjectsView. Problem is that you want to access from one user control child element of another user control. In my opinion it should be better solution to incapsulate all Login UI in LoginView user control and your "Projects" UI in ProjectsView user control.

EugenSoft
  • 536
  • 4
  • 13
  • The problem here is that I also need the password from the PasswordBox in elements/commands of `ProjectsView`. Then I would have the same problem vice versa :-) – Robert Strauch Dec 05 '12 at 14:12
  • If you use same ViewModel for both of your controls you can add in ViewModel some "Password" property, set this property in your LoginView and use it in ProjectsView via Binding. – EugenSoft Dec 05 '12 at 14:17
  • Yes, this would work. However this would violate soem security issues, right? I created a PasswordBox property now but it seems more like a dirty workaround though. Actually Microsoft must have some idea of how such a thing should be implemented? – Robert Strauch Dec 05 '12 at 19:36
  • It seems like MS not cares about any support of MVVM at all, so as for me property of type PasswordBox is good solution for security, and you can use it and don't care about such small violation of MVVM. Also there is another radical workaround: you can create one merged view instead of LoginView and ProjectsView. And then you can pass your PasswordBox as command argument as in your first example. – EugenSoft Dec 05 '12 at 20:03