Silverlight data binding to septate class c#

BrentDenny
BrentDenny used Ask the Experts™
on
I have a canvas that i need to add some mouse events like mouse-leave and mouse-enter  ect...

i have a separate class that is  will be handling the mouse events but i need to bind them from that page to the separate class NOT to code behind. Here is were i have bound to the class USAmap
i have used it and it works just fine for properties  but I dont now how to bind the mouse events for a canvas.
 
 <UserControl.Resources>
        <ViewModel:USAmap x:Key="ViewModel" MapItemName="USmap"/>
     </UserControl.Resources>
    <Grid x:Name="LayoutRoot" DataContext="{Binding Source = {StaticResource ViewModel}}">


<Canvas x:Name="Washington" Width="600" Height="398" Canvas.Left="0" Canvas.Top="0">
                    <Path x:Name="Path" Width="72.6667" Height="52.6219" Canvas.Left="38.831" Canvas.Top="19.7767" Stretch="Fill" Fill="#671BA51B" Data="F1 M 38.831,51.7767L ect...."/>
                </Canvas>

Also is there a way to still find out what the sender is and access it.
to change its properties once clicked. like in the code example

public class USAmap ......

 public static MouseButtonEventHandler _routedEvent;

public void c_MouseMove(object sender, MouseEventArgs e)
        {
            Canvas c = sender as Canvas;
            ResetLastSelected();

            if (!string.IsNullOrEmpty(c.Name))
            {
                if (c.Name != lastSelected)
                {
                 //   HideMenu();
                }

                lastSelected = c.Name;
                lastSelected2 = c.Name + "_HotSpot";
               // Canvas selectedCanvas2 = this.FindName(lastSelected2) as Canvas;

              //  SetCanvasColor(c, Color.FromArgb(255, 127, 255, 0), 2, Colors.Green, selectedCanvas2);
            }
        }

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Hi, you will need to use system.windows.interactivity.dll and
Microsoft.expression.interactions

You will need to use the CallMethodAction behavior

If you have Blend 4 then it would be easier for you to define it.

Author

Commented:
ok could you give me an example based on the code I gave you like on what pages I need to put what where and how it kinda all works together if you could please. Mean while ill see what i can find out about the interactivity and interactions  

I have blend but dont really know how to use it

Author

Commented:
P.S.I was trying to use the ICommand but since it only works that I can see for calling a fiction that doent work i need to access the sender to change it and it "e"  unless i am using it wrong.
Become a CompTIA Certified Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

Commented:
Hi, I'm working on an example for you... And yes, you can also get the sender and the event args if you use the CallMethodAction

Author

Commented:
do you use the
 <UserControl.Resources>
        <ViewModel:USAmap x:Key="ViewModel" MapItemName="USmap"/>
     </UserControl.Resources>
still ?

Commented:
You can do it differently..

Another way to set the DataContext is:

<UserControl.DataContext>
   <ViewModel:USAmap MapItemName="USmap"/>
</UserControl.DataContext>


Commented:
Hi, this is the XAML:

<UserControl
    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"
    xmlns:ViewModel="clr-namespace:SilverlightCallMethodAction.ViewModel"
[b]    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" [/b]x:Class="SilverlightCallMethodAction.MainPage"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <UserControl.DataContext>
        <ViewModel:USAmap MapItemName="USmap"//>
    </UserControl.DataContext>



    <Grid x:Name="LayoutRoot" Background="White">
        <Canvas x:Name="Washington" Width="600" Height="398" Canvas.Left="0" Canvas.Top="0" [b]Background="Transparent"[/b]>
[b]        	<i:Interaction.Triggers>
        		<i:EventTrigger EventName="MouseMove">
        			<ei:CallMethodAction TargetObject="{Binding}" MethodName="c_MouseMove"/>
        		</i:EventTrigger>
        	</i:Interaction.Triggers>[/b] 
           <Path x:Name="Path" Width="72.6667" Height="52.6219" Canvas.Left="38.831" Canvas.Top="19.7767" Stretch="Fill" Fill="#671BA51B"/>
        </Canvas>
    </Grid>
</UserControl>

Open in new window


Please note that I've added xmlns "i" and "ie".
You will need the DLLs I've mentioned earlier to be added to your references,

You will also see that the canvas background must have a value (else it is Null and therefore Hit Test does not happen).

And you will also see the section where I've defined the CallMethodAction.

Commented:
The XAML got a little corrupted.. I added Bold , but the Code tags ignored it. Here it is without code tags:

<UserControl
    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"
    xmlns:ViewModel="clr-namespace:SilverlightCallMethodAction.ViewModel"
   xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class="SilverlightCallMethodAction.MainPage"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <UserControl.DataContext>
        <ViewModel:USAmap MapItemName="USmap"//>
    </UserControl.DataContext>



    <Grid x:Name="LayoutRoot" Background="White">
        <Canvas x:Name="Washington" Width="600" Height="398" Canvas.Left="0" Canvas.Top="0" Background="Transparent">
             <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseMove">
                          <ei:CallMethodAction TargetObject="{Binding}" MethodName="c_MouseMove"/>
                    </i:EventTrigger>
              </i:Interaction.Triggers>

           <Path x:Name="Path" Width="72.6667" Height="52.6219" Canvas.Left="38.831" Canvas.Top="19.7767" Stretch="Fill" Fill="#671BA51B"/>
        </Canvas>
    </Grid>
</UserControl>

Author

Commented:
Ok so first I am assuming that I have to do that for every mouse event like mouse leave  mouse over  ect i have 4 mouse events i need to do.  Also i have like 50 canvases (STATEs)with  the same with different points so is there a good way besides this to this to each State?

so would i have to do this?  and would i have to do this for each State or is there a better solution?

 Background="Transparent">
             <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseMove">
                          <ei:CallMethodAction TargetObject="{Binding}" MethodName="c_MouseMove"/>
                    </i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
                          <ei:CallMethodAction TargetObject="{Binding}" MethodName="c_MouseMove"/>
                    </i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonUp">
                          <ei:CallMethodAction TargetObject="{Binding}" MethodName="c_MouseMove"/>
                    </i:EventTrigger>
<i:EventTrigger EventName="MouseLeftUp">
                          <ei:CallMethodAction TargetObject="{Binding}" MethodName="c_MouseMove"/>
                    </i:EventTrigger>

              </i:Interaction.Triggers>

Commented:
You will need to have all 4 events defined in XAML since each of them calls a different function (or at least should)... and some of the events have different event args (on Mouse Move you have different args than mouse button down).


About the 50 canvases, then first, if you have in the same XAML 50 different canvasses then you are doing something wrong.

If each of the canvasses is located on a different XAML then maybe the method name is not the same...

If it does, then maybe define a UserControl that contains a Canvas with those events and just put this UserControl in anywhere you want (50 times if needed).
This way you only need to write events definitions once.

Author

Commented:
ok i am going to give you 3 of them out of the 50 so you under stand there the USA states that are paths that i am using the canvases to change colors and opacity depending on the mouse events.
They will all call the same mouse events  so all 4 mouse events need to be tied to each 50 states

<Canvas x:Name="Oregon" Width="600" Height="398" Canvas.Left="0" Canvas.Top="0">
                    <Path x:Name="Path_1" Width="86.8889" Height="74.2222" Canvas.Left="19.2755" Canvas.Top="51.7767" Stretch="Fill" Fill="#671BA51B"
 Data="F1 M 19.7199,107.777L 19.2755,104.666L 19.7199,107.777 Z "/>
                </Canvas>
<Canvas x:Name="Califonia" Width="600" Height="398" Canvas.Left="0" Canvas.Top="0">
                    <Path x:Name="Path_3" Width="87.1111" Height="149.111" Canvas.Left="11.2755" Canvas.Top="107.554" Stretch="Fill" Fill="#671BA51B" Data="F1 M 19.9421,107.554L 37.7199,112.888L 47.2755,115.332L 55.7199,117.332L 61.0533,118.666L 60.1644,122.666L 57.9421,130.888L 56.1644,136.888L 54.6088,144.888L 107.554 Z "/>
                </Canvas>
 <Canvas x:Name="Arizona" Width="600" Height="398" Canvas.Left="0" Canvas.Top="0">
                    <Path x:Name="Path_5" Width="74" Height="85.8333" Canvas.Left="87.1366" Canvas.Top="200.443" Stretch="Fill" Fill="#671BA51B" Data="F1 M 87.9699,256.11L 88.9699,256.943L 90.6366,256.61L 91.9699,255.277L 91.9699,253.777L 90.4699,252.777L 89.6366,251.443L 89.6366,248.61L 90.4699,246.777L 92.1366,1366,257.777L 87.9699,256.11 Z "/>
                </Canvas>

Author

Commented:
P.S. the test is working just need think is there something in the app.xaml  that would be a good idea not sure i have just stared learn silver light 2 weeks ago.

Commented:
Can't you gave just one canvas, and have all the paths in it??
Can't you on the mouse move of the canvas find which path your mouse is on?

Author

Commented:
not total because some states have multiple paths and the there would be a lot of code re-write since everything works i just pulling out every thing from the code be hind to a class that I can use the mvvm model more effectively since there are multiple maps that will use this class, so that would be counter productive there will be 50 other maps with similar attributes especially the mouse events

Author

Commented:
oops So i was hopping for like a for global event thing that the each canvas can use

Commented:
well, if you really want to have it on the canvas without replicating the code then maybe you can create your own class that derives from Canvas.

In your class (Lets call it MyCanvas) code-behind register to the events you want...
And then do:
dynamic dataContext = this.DataContext;
dataContext.c_MouseMove(sender, e);

I'm using dynamic here, cause the canvas doesn't know the type of the viewmodel... I know, this is ugly.


A more proper design would be having an ItemsControl which has the ItemsPanel as Canvas and then the DataTemplate of the Items would be paths... just a suggestion.
I know DataTemplate is not supported by Silverlight, but you can still do it with a Converter. (a Converter that converts a ViewModel to it's proper UI).

Author

Commented:
I was going to try the approce of using the MyCanvas  but i am not sure what you mean by register to the the event and not sure where and what to do with the dynamic dataContext = this.DataContext;
dataContext.c_MouseMove(sender, e); sorry i was trying to look for examples but have found none
  public class CustCanvas : Panel
    {
        public CustCanvas()
        {
            dynamic dataContext = this.DataContext;
        //dataContext.c_MouseMove(sender, e);
        }
       
       // put the mouse event here or some how conect back to USAmap using a deligate?
        public void c_MouseMove(object sender, MouseEventArgs e)
        {
         
        }

    }
Commented:
You need to add reference to Microsoft.CSharp.
I didn't have a chance to test the code. It compiles and I assumes that it will work.

    public class CustCanvas : Canvas
    {
        public CustCanvas()
        {
            this.MouseMove += new MouseEventHandler(CustCanvas_MouseMove);
            this.MouseEnter += new MouseEventHandler(CustCanvas_MouseEnter);
            this.MouseLeave += new MouseEventHandler(CustCanvas_MouseLeave);
            this.MouseLeftButtonUp += new MouseButtonEventHandler(CustCanvas_MouseLeftButtonUp);
            this.MouseLeftButtonUp += new MouseButtonEventHandler(CustCanvas_MouseLeftButtonUp);
        }

        void CustCanvas_MouseEnter(object sender, MouseEventArgs e)
        {
            dataContext.C_MouseEnter(sender, e);
        }

        void CustCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            dataContext.C_MouseLeftButtonUp(sender, e);
        }

        void CustCanvas_MouseLeave(object sender, MouseEventArgs e)
        {
            dataContext.C_MouseLeave(sender, e);
        }

        void CustCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            dataContext.C_MouseMove(sender, e);
        }

        private dynamic dataContext
        {
            get
            {
                return this.dataContext;
            }
        }
    }

Open in new window

Author

Commented:
I thank you for you solution i could not get the exact something to work kept giving me a circle reference not sure why but then i just took out from the class i had and just used this as a template and it works great  for your help i am going to close this i need help with another problem and would like you get get more credit for it so i am going to call it navigation Sivlerlight

Author

Commented:
THanks again

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial