How to Access a Control on MainPage from Page1 using Binding and MVVM

This question is related very closely to a question I asked earlier on this Forum. My original question has been answered very kindly by Sargani. Sargani has also suggested the best approach to solve my problem would be using Binding and have my code written using MVVM (No code behind). The solution provided by Sargani is working fine, but  I would like to understand and learn this alternative approach also and would be grateful for help with this.
My original question and its solution are posted here.
I have put the XAML for all three pages in my Project and their relavant code behind in my original question.
I would rephrase my original question here as follows.
I have a very simple Silverlight Application with a MainPage and two other Pages (Page1 and Page2). MainPage has two Grids. One of the Grid has a couple of Buttons  (cmdPage1 and cmdPage2) and a RichTextBox named  txtNotes on it. Clicking one of the these Buttons (cmdPage1) opens Page2 into the second Grid on Main page as its child. I would like to be able to type a word such as  “Happy” into  txtNotes, programmatically by clicking  a button on Page1 which is visible inside MainPage as its Child after clicking cmdPage1 on MainPage . To achieve this I need to access txtNotes on MainPage from the Click event of the Button on Page1. However this was not easy.
Who is Participating?
Hi, sorry for the delay.
I don't know if you know anything about Binding and Commands (and now also Behaviors), but that's the power of WPF and Silverlight.

If you are writing code as you wrote in the link you posted, it's like you are writing a WinForms application.
I know some doctor who calls it a WPF Duck, because:
"If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck"
(Also known as the "Duck Test").

Binding let you bind a property in XAML to another property (Which can be either in your XAML or in your DataContext).

Lets take a TextBlock for example, we would like to bind the text property to the TextProperty of a TextBox.... so if we change the text of a TextBox, the text in the TextBlcok will also change.
Using the old method you would have registered to the "text changed" event and then change the text on the TextBlock.
With Binding you just write:

<TextBox x:Name="txtBox1"/>
<TextBlock Text="{Binding ElementName=txtBox1, Path=Text}" />

The bold text is the Source property
<TextBlock Text="{Binding ElementName=txtBox1, Path=Text}" />

The bold text is the Target property
<TextBlock Text="{Binding ElementName=txtBox1, Path=Text}" />

Beside "Path" and "ElementName" you can also define Mode (OneWay, TwoWay or OneTime... One time means that it will read the text from the textbox only one time and then it will not update).

Sometime you also want to take one value and convert it to another value. In this case we will use a Converter. Let's have also a checkbox that changes the Visibility of the TextBlock.
We will need to convert Boolean to Visibility, let's see an example:

<UserControl x:Class="Silverlight_MVVM_Example.MainPage"
    d:DesignHeight="300" d:DesignWidth="400">
        <local:FlippedBoolToVisibilityConverter x:Key="flippedBoolToVisibilityConverter" />

    <StackPanel Background="White">
        <TextBox x:Name="txtBox1"/>
        <TextBlock Text="{Binding ElementName=txtBox1, Path=Text}" Visibility="{Binding ElementName=chkBox1, Path=IsChecked, Converter={StaticResource flippedBoolToVisibilityConverter}}" />
        <CheckBox x:Name="chkBox1" Content="Hide TextBlock" />

And the code of the converter:
using System;
using System.Windows;
using System.Windows.Data;

namespace Silverlight_MVVM_Example
    public class FlippedBoolToVisibilityConverter : IValueConverter

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            bool val = (bool)value;

            if (val)
                return Visibility.Collapsed;

            return Visibility.Visible;

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            throw new NotImplementedException();


The Target property (<TextBlock Text="{Binding ElementName=txtBox1, Path=Text}" />) must be a DependencyProperty!!!

RichTextBox (at least in WPF) text/document property is not a dependency property!!!
So I will make my example with a simple text box.

However, you can probably find on CodeProject or CodePlex a RichTextBox for silverlight that works with Binding (There is one for WPF under the Extended WPF toolkit).

Another solution for the binding problem of the RichTextBox is to have 1 paragraph and use "Run":

                <Run Text="{Binding ElementName=txtBox1, Path=Text}" />

MVVM stands for Model-View-ViewModel.
The whole idea is to remove dependencies of UI and Model. Your Model should not know what UI you have.
UI should not contain Busyness Logic!!!

Therefore, you should not use Click events on buttons.
Instead, there are Commands.

Buttons have a property called Command which accept an ICommand object (Which can be given by Binding).
This way you can give it code that is located in your ViewModel/DataContext so the code will not run on your UI, but in your ViewModel.

Buttons are the only UI Element that have Commands support, and it only works on Click...
However, you can use Blend and Behaviors and use CallMethodAction in order to invoke Commands or Actions on your ViewModel on other UI Elements an on any event!!! (Which is great).

It would be hard to explain the whole MVVM, Binding etc in such a small post.

Just look for MVVM and Binding in Google. There  are lots or articles.
Anyway, I'm posting (attaching it to a MegaUpload) a code example + an eBook that explains WPF in a very good way. It also explains Binding.

In WPF there is DataTemplate and you can define that for DataType (Your view Model) it will define the View
Unfortunately, in Silverlight the DataType property is not available... It will be on Silverlight 5.0, for now, we will need to use a Converter (ViewModelToViewConverter)!!

Another problem is that RelativeSource in Sliverlight only supports TemplateParent and Self (No FindAncestor support), so I cannot make the button on Page1 to execute a command on MainPage in an easy way,
I will need an Event... Another solution is using the idea posted here:


WPF eBook:
FaheemAhmadGulAuthor Commented:
Thank you very much. It has been extremely helpful. Your detailed explanation has introduced me to new concepts and I have started studying them. I am not a professional programmer and am learning programming as a hobby. I find it extremely stimulating intellectually and am very keen to learn new concepts.
Thank you also for the Ebook and Sample Code. Regards
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.