Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

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

Posted on 2011-04-30
2
Medium Priority
?
638 Views
Last Modified: 2013-11-12
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.
http://www.experts-exchange.com/Microsoft/Development/Microsoft_Programming/WPF_and_Silverlight/Q_26986900.html?cid=239#a35497889
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.
0
Comment
Question by:FaheemAhmadGul
2 Comments
 
LVL 11

Accepted Solution

by:
saragani earned 2000 total points
ID: 35499796
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"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:local="clr-namespace:Silverlight_MVVM_Example"
    d:DesignHeight="300" d:DesignWidth="400">
   
    <UserControl.Resources>
        <local:FlippedBoolToVisibilityConverter x:Key="flippedBoolToVisibilityConverter" />
    </UserControl.Resources>

    <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" />
    </StackPanel>
</UserControl>


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

        #endregion
    }
}




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":

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







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: http://blog.thekieners.com/2010/09/08/relativesource-binding-with-findancestor-mode-in-silverlight/


Code:
http://www.megaupload.com/?d=760XG9K8

WPF eBook:
http://www.megaupload.com/?d=PHM90Y19
0
 
LVL 1

Author Closing Comment

by:FaheemAhmadGul
ID: 35499984
Excellent!!
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
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question