0

The UserControls are put into MainWindow but they don't instantiate each other - they don't have owner-member relationship.

I need the back-end code of UserControls to be able to get the value from a TextBox of MainWindow. I have been told to use data binding but I don't really know what to be bound in UserControls.

Create an interface:

interface Interface_ProSimIP
{
    string ProSimIP_Text { get; set; }
}

In MainWindow ViewModel:

    string Interface_ProSimIP.ProSimIP_Text
    {
        get
        {
            return ProSimIP.Text;
        }
        set
        {  
        }
    }

In MainWindow View:

<TextBox x:Name="ProSimIP" Text="{Binding Path=ProSimIP_Text, Mode=OneWay}..."

I don't know am I right to do it this way and I don't know how to implement the interface in UserControls code behind.

mm8
  • 163,881
  • 10
  • 57
  • 88
water
  • 138
  • 10
  • Not sure if I understand you correctly. But if you want the Data that user types in textbox to be available as a string variable in the code behind (or VM) you can Bind it like: – Prateek Shrivastava Dec 12 '17 at 09:41
  • "I need the back-end code of UserControls to be able to get the value from a textbox of MainWindow". That is a wrong approach in WPF environment. If your UserControl needs any data, declare a DependencyProperty for that data and bind the DP from main view – ASh Dec 12 '17 at 09:41
  • When you say "UserControl ViewModels" it sounds like you think each UserControl should have its own view model. Although this is quite often suggested by "WPF experts", it's absolutely wrong. A UserControl should never have a view model of its own. Instead, it should expose dependency properties that can be bound (usually, but not necessarily, to view model properties). – Clemens Dec 12 '17 at 09:42
  • Bind the TextBox in the window and the UserControl to the same DataContext. – mm8 Dec 12 '17 at 09:52
  • Many thanks. Prateek Shrivastava I want the value in a Window to be available for a UserControl. ASh OK I will have a try. @Clemens by "UserControl ViewModels" I mean UserControl.xaml.cs. am I calling its wrong name or they should not contain any code except data-binding? – water Dec 12 '17 at 09:54
  • @mm8 Sorry I don't quite understand. – water Dec 12 '17 at 09:57
  • That's called the UserControl's code behind (not view model). So what you should do is declare a dependency property, which can be bound like ``. To get notified in the UserControl's code behind about when the property's value gets set, register a PropertyChangedCallback. Start reading here: [Custom Dependency Properties](https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/custom-dependency-properties). – Clemens Dec 12 '17 at 09:58
  • When you've done that, you can of course directly bind your property to the Text property of a TextBox like ``. However, the recommended approach is to use a common view model, i.e. bind both controls to the same view model object (held by the DataContext property), like `` and ``. The view model would have to implement the INotifyPropertyChanged interface and fire the PropertyChanged event when ProSimIP_Text changes. – Clemens Dec 12 '17 at 10:15
  • @Clemens What I originally thought was a view model is actually not. What is a common view model? – water Dec 12 '17 at 10:21
  • It's an object that you assign to the DataContext of your MainWindow, e.g. in the MainWindow constructor like `DataContext = new ViewModel();`. It has properties that typically fire the PropertyChanged event, and the UI (view) element properties are bound to. – Clemens Dec 12 '17 at 10:23
  • @Clemens Thanks. I am still not clear about it now. I need to learn it to have deeper understanding. But your comment really helps! – water Dec 12 '17 at 10:29
  • https://stackoverflow.com/questions/1315621/implementing-inotifypropertychanged-does-a-better-way-exist – Blacktempel Dec 12 '17 at 13:27

1 Answers1

1

You could use the same DataContext (view model) for the parent window and the user controls. Set the DataContext property of the window to an instance of a view model class where you implement your logic and then bind to properties of the view model from the XAML views of the window and the user controls. Then the window and the controls effectively share the same "back-end" code.

This pattern is known as MVVM and it's the recommended pattern to use when developing XAML based UI applications. You should learn it. The following MSDN page might be provide a good starting point for you: https://msdn.microsoft.com/en-us/library/hh848246.aspx.

Another (worse but maybe faster to adopt if you don't know anything about nor follow the MVVM pattern) approach would be to get a reference to the window from the UserControl using the Window.GetWindow method, and then access any control that's defined in the window directly:

var window = Window.GetWindow(this) as MainWindow:
if (window != null)
    string text = window.ProSimIP.Text;

You should note that this kind of code doesn't follow follow best practices when it comes to developing loosely coupled, maintainable and testable applications though.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Thanks. Although it is not the best practice, it also seems not practical to change my former design. I will try it tomorrow. – water Dec 12 '17 at 10:34