MVVM Light - Relay Command Value parameter that arrives intermittently

I am using the silverlight app. An attempt to associate a button command with a relay command in the ViewModel and pass some parameters to it. Code for my view:

<Button x:Name="button" Content="Button" VerticalAlignment="Top" Margin="173,0,152,0"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction CommandParameter="{Binding ActualWidth, ElementName=button, Mode=TwoWay}" Command="{Binding CRelayDecimal, Mode=OneWay}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> 

The button passes the ActualWidth value as a parameter to the command parameter. My ViewModel Code:

 public Page1() { InitializeComponent(); CRelayDecimal = new RelayCommand<Object>(this.GetDecimal); } public RelayCommand<Object> CRelayDecimal { get; private set; } private void GetDecimal(Object Obj) { var value = (double)Obj; } 

Now the problem that I see here is that in most cases the value of the parameter I get is 0.0. With interruptions, I saw that the value was the exact value (e.g. 75.0) that should be.

Is there any other way to do this?

Thank you all for your help in advance.

Thanks and Regards

Nishant Rana

+4
source share
4 answers

Good. Got an answer why this doesn't work ... because it is a known issue in silverlight.

Read this for more details from MSFT.

+1
source

I think it pulls the "ActualWidth" binding value from the DataContext, which is most likely the ViewModel (where ActualWidth does not exist as a property).

It might work. You can try setting "this.button.DataContext = this;" in the Loaded event handler of your view code. Thus, the view becomes the first data type of the button. Unresolved binding properties, such as CRelayDecimal, should still return to the ViewModel.

Or maybe the easiest task is to simply connect a regular click handler to the button to process the view code. The view code would compute ActualWidth from the event sender and send a RelayCommand to the model as needed.

+1
source

Yes, there is at least one other to do this. From your example, it makes no sense to use Command because you just want to send the value from the View to the ViewModel.

I suggest you use Messenger to send values ​​between View and ViewModel. What you need to do:

1) Register the message in your ViewModel. I prefer to do this in my constructor. You must also add a method to handle the callback from the messenger. Please note that "tokenId" used to make sure that you are sending a message to subscribers.

 Messenger.Default.Register<double>(this, YourMethodHere, "tokenId"); private void YourMethodHere(double value) { // do your work here } 

2) Inside the view, you need to add an event to the button and just send a message through the messenger.

 private void Button_Click(object sender, RoutedEventArgs e) { Messenger.Default.Send<double>(this.ActualWidth, "tokenId"); } 

3) You can Unregister subscription to ViewModel in your destructor to prevent reciprocal sending of messages.

+1
source

Thanks guys for your feedback!

I examined it further and found that the problem is related to the property ie "ActualWidth" that belongs to me. If I try to bind it to the Width property, then it works fine.

Therefore, I believe that it takes only the initialization value for the ActualWidth property.

Let me do some more tests, and then I will get back to you with more results.

Thanks and Regards

Nishant Rana

+1
source

Source: https://habr.com/ru/post/1442664/


All Articles