Trying to use eventtocommand on a grid.

Oct 28, 2011 at 1:54 PM

Hi there,

I want to catch a click / mouseleftbuttondown event on my grid.

I looked at the example in the documentation, but no luck.

I succesfully managed to put a MouseRightbuttonDown on  a listbox and the mousemove did work to.

Binding events to a grid, rectangle,... didn't seem to work. My XAML Looks like this:

<Grid Grid.Row="3" Grid.Column="1" Background="#FFFADA2B" Margin="5" Cursor="Hand" >
   <i:Interaction.Triggers>
      <i:EventTrigger EventName="MouseLeftButtonDown">
         <catel:EventToCommand Command="{Binding MouseLeftButtonDownCommand}" DisableAssociatedObjectOnCannotExecute="False" />
      </i:EventTrigger>
   </i:Interaction.Triggers>
</Grid>

The code in the viewmodel is this:

Public Property MouseLeftButtonDownCommand As Catel.MVVM.Command
MouseLeftButtonDownCommand = New Catel.MVVM.Command(AddressOf onMouseLeftButtonDownCommand)
Private Sub onMouseLeftButtonDownCommand()
   Console.WriteLine("")
End

There's a breakpoint on the console.writeline, but it never hits.

Is it possible to put an eventtocommand on a grid, and if so what am I missing here?

Thanks in advance

Oct 28, 2011 at 2:27 PM

At first sight, what you are doing is correct. You might want to try and add a CanExecute as well and see if that one is being executed. Also make sure to check the output window for binding errors.

Oct 28, 2011 at 2:44 PM

Hey

Thank you for the quick reply. I've already tested with the canExecute, and it isn't called either.

I've been looking at the output window and I see a few errors, but none of them should relate to the events. One error describes it cannot read the assembly Silverlight.Toolkit.

The other error is more vague: 03:35:33:281 => [ERROR] [Catel.Argument] Argument 'name' cannot be null or whitespaceA first chance exception of type 'System.ArgumentException' occurred in Catel.Silverlight

The output window also shows that the commands are registered, so no clue what it is.

Oct 30, 2011 at 7:59 PM

Seems to be a SL issue, works great in WPF. Will investigate this further and let you know.

Oct 30, 2011 at 8:17 PM

And the issue is fixed. In Silverlight, the IsEnabled is only available on classes deriving from Control (and Grid doesn't). So, Catel defaults back to an "is enabled" state of false, which is now set to true if the state cannot be determined.

You can get the latest beta here:

http://dl.dropbox.com/u/8455721/Catel%20beta.zip

Oct 31, 2011 at 10:38 AM

Hi

I've tried the new beta and at first sight it seems to work perfectly. My grid redirects it's mouseleftbuttondown to the viewmodel.

Thanks for the fix.

Nov 3, 2011 at 10:03 AM

Hi

I've been using the 2.4 version of the dll now and it shows a big issue. I'm using WCF services to get items from the server. When the item gets back, I need to display it for the user, but it never gets there.

The service gets back to the client, calls the onEndGet btu then it falls in some kind of loop. When I look in the debugger, there's an outrage of information there. This keeps on happening for over 10 minutes (then i quit debugging) so the information is never displayed.

Is this something you recognize?

Nov 3, 2011 at 10:06 AM

Was it working in the official 2.3 release? Do you have a small repro?

Nov 3, 2011 at 10:11 AM
Edited Nov 3, 2011 at 10:20 AM

It even worked in the 2.3 beta...

I was gonna take a screenshot, but doing a get latest version from my collegue got me other problems so I cannot reproduce it at the moment.

What I'm seeing in the output is hundred thousands of lines of [DEBUG] information.

 

Edit (here's some lines from the output):

10:11:57:243 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Non-generic .NET system type, can be ignored
10:11:57:243 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for property 'Item' of 'ItemManagementTool.Model.Item.ItemCollection'
10:11:57:244 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for 'ItemManagementTool.Model.Item.ItemBase'
10:11:57:244 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for property 'Id' of 'ItemManagementTool.Model.Item.ItemBase'
10:11:57:245 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for 'System.Int32'
10:11:57:245 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Non-generic .NET system type, can be ignored
10:11:57:246 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for property 'Code' of 'ItemManagementTool.Model.Item.ItemBase'
10:11:57:246 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for 'System.String'
10:11:57:247 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Non-generic .NET system type, can be ignored
10:11:57:247 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for property 'Language' of 'ItemManagementTool.Model.Item.ItemBase'
10:11:57:248 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for 'ItemManagementTool.Model.Language.Language'
10:11:57:248 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for property 'ID' of 'ItemManagementTool.Model.Language.Language'
10:11:57:249 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for 'System.Int32'
10:11:57:249 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Non-generic .NET system type, can be ignored
10:11:57:249 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for property 'Guid' of 'ItemManagementTool.Model.Language.Language'
10:11:57:250 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Getting known types for 'System.Guid'
10:11:57:250 => [DEBUG] [Catel.Runtime.Serialization.SerializationHelper] Non-generic .NET system type, can be ignored

Nov 3, 2011 at 10:29 AM

Does it only happen when calling WCF services (Async calls)?

Or can you reproduce it without a WCF Call?

Nov 3, 2011 at 10:35 AM
Edited Nov 3, 2011 at 11:45 AM

Hey

We're only serializing our data to send it over WCF, so thusfar, it's only been with wcf calls.

Don't get me wrong, getting the data works, I'm hitting my breakpoints on the serverside. I even return to the client, there it starts going wrong (since update Catel.Silverlight 2.3 to 2.4).

We've managed to replicate this is the 2.3 as well in the meanwhile.

Nov 3, 2011 at 1:53 PM

Hi, I'm the colleague of djerry. I can serialize and deserialize data using the Catel.core. I can make an object, serialize it to a stream and save it in the database, retrieve it from the database and deserialize it.

The problem occurs when we send the object through to our application. Using fiddler we see our object coming through the service to our client, but then starts the overload on debug info in the output window.

I had it working this morning (on a 2.3 beta release of 12/10-18/10) , but after updating to the latest version this morning, never got it back to work again.

Nov 3, 2011 at 1:58 PM

Would you mind sending us the classes that are sent over the wire? Then we will try to reproduce it and fix it for you. Deserialization in silverlight can be a bit complex, because the DataContractSerializer needs to be aware of all types. However, it is strange that Silverlight has issues deserializing it, because it uses exactly the same code as the WPF (.NET) implementation.

If you don't want the classes to become public, contact me via the support and I will provide my e-mail address.

Nov 3, 2011 at 5:05 PM

Hi we found something that solved our problems. Our object had a constructutor that initialised a member with a new instance of another object. We commented that line and it worked.

Public Sub New() 
	'CreatedBy = New User.User
End Sub
Nov 3, 2011 at 5:26 PM

Great to hear. Keep in mind that it is better to set default values via the property registration (and for instances, you should use the delegate). See this blog post for more details.

Dec 16, 2011 at 9:53 AM

Hello 

Today, I came accross the blog post you linked earlier. I thought it would solve a problem I've been having but it doesn't really.
In a certain viewmodel, we have a property with the model attribute to it. Then we make 2 properties with the viewmodeltomodel attribute realting to the property listed before. It looks like this:

Public Shared ReadOnly CurrentUserProperty As Catel.Data.PropertyData = RegisterProperty("CurrentUser", GetType(User), Function() New User())
<Catel.MVVM.Model()>
Public Property CurrentUser As User
    Get
        Return GetValue(Of User)(CurrentUserProperty)
    End Get
    Set(value As User)
        SetValue(CurrentUserProperty, value)
    End Set
End Property

Public Shared ReadOnly UsernameProperty As Catel.Data.PropertyData = RegisterProperty("Username", GetType(String))
<Catel.MVVM.ViewModelToModel("CurrentUser", "Username")>
Public Property Username As String
    Get
        Return GetValue(Of String)(UsernameProperty)
    End Get
    Set(value As String)
        SetValue(UsernameProperty, value)
    End Set
End Property

Public Shared ReadOnly PasswordProperty As Catel.Data.PropertyData = RegisterProperty("Password", GetType(String))
<Catel.MVVM.ViewModelToModel("CurrentUser", "Password")>
Public Property Password As String
    Get
        Return GetValue(Of String)(PasswordProperty)
    End Get
    Set(value As String)
        SetValue(PasswordProperty, value)
    End Set
End Property

 

In our view, we bind the username and password properties to 2 textboxes. When loading the page, the properties don't have a value. So the user needs to type his username and password. Those items are set to the 2 properties. But I thought setting those 2 properties would also update the CurrentUser property, which doesn't happen.

I've tried registering the property like this too:

Public Shared ReadOnly CurrentUserProperty As Catel.Data.PropertyData = RegisterProperty("CurrentUser", GetType(User), New User())

This leads to the same result, the CurrentUser property isn't updated, but with this way of registering, the validation works on the textboxes, with the one stated first, I don't get the red lines around the textboxes.

I also initialised the CurrentUser in the constructor, but that's not the way to go either.

 

Any thoughts on this?

Thanks in advance.

Dec 16, 2011 at 10:13 AM

1) The property registration with the new user is good, using it as a delegate.

2) I see that you are using ViewModelToModel("CurrentUser", "Password"), but the second parameter ("Password") is not required when the properties have the same name.

3) Can you post the model declaration? It's hard to find the issue without knowing how the model validations.

For example, have you tried setting a breakpoint in the setter of the "Username" property and see if the CurrentUser has an actual value?

Dec 16, 2011 at 2:08 PM

Step 1: when using the delegate, my currentUser is nothing, it doesn't get a default new user value. (and validation doesn't work, can't see red outline on textboxes)

Good to know step 2.

For step 3, when the code hits the username property, i'm going to my watches and the username property on the CurrentUser is still nothing.

So my CurrentUser just stays a new user object. But here, the validation shows in the UI.

 

My user object has approx 10 properties, all declared like the one below:

Public Shared ReadOnly GuidProperty As Catel.Data.PropertyData = RegisterProperty("Guid", GetType(Guid))
Public Property Guid As Guid Implements IUser.GUID
    Get
        Return GetValue(Of Guid)(GuidProperty)
    End Get
    Set(value As Guid)
        SetValue(GuidProperty, value)
    End Set
End Property

The class user also inherits from Person. I think the user class and all related classes is too much to post here.

Dec 16, 2011 at 3:51 PM

Strange, setting the default value must work. Are you sure you are not binding the model two-way to something in the view or setting it to null somewhere? Try making the setter private and see if it is used anywhere.

Dec 16, 2011 at 3:54 PM

We do have it bind like this:

<Catel:WarningAndErrorValidator Source="{Binding CurrentUser}" Height="100" Background="#ff0000" />
Can this be what causes the CurrentUser to be nothing?

Dec 16, 2011 at 3:55 PM

That's a read-only binding, shouldn't do anything. But, you probably want to bind to the view model instead of the model. So I always recommend to use Source="{Binding }" for such things.

Dec 16, 2011 at 3:59 PM

Ok, good to know.

There's no other place where we bind to CurrentUser. When using the delegate the userobject stays nothing. When just saying new user, the default value is set.

In both cases, the username property isn't called (in the first scenario, that should throw an error cause the object is nothing)

Dec 16, 2011 at 4:00 PM

Very weird, can you write a very small repro? Never seen something like this before.

Dec 17, 2011 at 6:56 PM

I think this is related to http://catel.codeplex.com/discussions/282943

Repro:

-Start from the Person SL sample.
-Add a Dog class (model), with one Name property.
-Add a Dog property to the Person model class.
-In the PersonViewModel, add a Dog property decorated with [Model] and [ViewModelToModel] and ()=>new Dog() as last parameter
-Also add a DogName property decorated with [ViewModelToModel("Dog")]
-Add the DogName field to the PersonView
-Run->add person->fill in data (including the dog's name)->check Person.Dog of the newly added person (will be null) Hey? where did my dog go? :-)

(I also encountered this issue earlier, and worked around it by, in the viewmodel that has the Add command, in the Add command, creating both the Person and the Dog and assigning the Dog to the person:

Person person = new Person();
person.Dog=new Dog();

 

Dec 18, 2011 at 11:55 AM

This issue should be fixed in the latest version.

Dec 19, 2011 at 3:02 PM

I've made a small application which reproduces the issue, how can I deliver that?

Dec 19, 2011 at 3:16 PM
Edited Dec 19, 2011 at 3:22 PM

I cannot contact you via codeplex (seems you have disabled that option). You can e-mail me [removed].

Dec 19, 2011 at 3:47 PM

You should have received an email with the application. I hope you see the problem.

Dec 20, 2011 at 7:13 PM

The RegisterProperty doesn’t use the right overload. I have no experience with VB.NET, but the Function is passed as object instead of a function. You should find out how you can make it use the overload (cast it, I have no idea because I have not enough experience with VB.NET).

Sorry, it's all info I can give you at the moment.