Use MVVM to change Slider Value

Nov 24, 2011 at 2:01 AM

Hi all,

I want to use Slider to change property of Model and call another method after setter method run. And my model like this:

public class ModelTest
    {
        #region Variables
        private double size = 0.5;
        #endregion

        #region Constructor & destructor
        public ModelTest()
        {
        }
        #endregion

        #region Properties
        public double Size
        {
            get { return size; }
            set { size = value; }
        }

}

I bind this Model to the ViewModel and use ViewModelToModel Propery for Size property.

And the Slider I use this code:

<Slider Width="80" HorizontalAlignment="Left" VerticalAlignment="Center" x:Name="slrSize" Value="{Binding Size}"/>

But when I change the value of slider, the setter method in the ViewModel don't be call.

I don't want to use EventToCommand Trigger.

Please help me find out the solution for this situation.

Thanks a lot.

Coordinator
Nov 24, 2011 at 7:50 AM

I do not see whether you are using WPF or Silverlight. There are a few options here:

1) You are using Silverlight, then simply set the binding mode to TwoWay (Value="{Binding Size, Mode=TwoWay}")

2) The setter in the view model is not called in WPF because internally a ICustomTypeDescriptor is created which directly calls the SetValue for the property (just the way dependency properties work).

Can you show the property definition on your view model for both the ModelAttribute and the ViewModelToModelAttribute?

Nov 24, 2011 at 9:40 AM

Hi GeertvanHorrik,

Thanks for your reply soon.

Now i am using WPF to learn your MVVM framework.

This is my ViewModel:

public class MediaPlayBackModel : ViewModelBase
{

        public MediaPlayBackModel()
        {
            MediaPlayBack = GetService<IMediaPlayBack>();

        }

        [Model]
        public IMediaPlayBack MediaPlayBack
        {
            get { return GetValue<IMediaPlayBack>(MediaPlayBackProperty); }
            private set { SetValue(MediaPlayBackProperty, value); }
        }

        public static readonly PropertyData MediaPlayBackProperty = RegisterProperty("MediaPlayBack", typeof(IMediaPlayBack));

        [ViewModelToModel("MediaPlayBack")]
        public double Size
        {
            get { return GetValue<double>(SizeProperty); } 
            set { SetValue(SizeProperty, value); }
        }


        public static readonly PropertyData SizeProperty = RegisterProperty("Size", typeof(double));

}

When I debug, the setter method is called in ModelTest class, not the setter method in the ViewModel class.

I want when I change the value of Slider, the setter Size in ViewModel will be called so that I can call the next method to do something with the new value of Size property.

Coordinator
Nov 24, 2011 at 10:09 AM
Edited Nov 24, 2011 at 10:10 AM

This is because a custom type is injected between the View and the ViewModel to allow the ExposeAttribute to be used. If you want changes, register your property like this:

 

public static readonly PropertyData SizeProperty = RegisterProperty("Size", typeof(double), default(double), (sender, e) => ((MediaPlayBackViewModel)sender).OnSizeChanged());

private void OnSizeChanged()
{
    GetService<IMessageService>().Show("Size has changed!");
} 

 

 

Nov 24, 2011 at 10:41 AM

Hi GeertvanHorrik,

Thanks a lot, it works for me. This is the solution I want.

By the way, can you show me the document talk about the "a custom type is injected between the View and the ViewModel to allow the ExposeAttribute to be used" that you focus above. I want to clear this idea. :)

Coordinator
Nov 24, 2011 at 10:44 AM

It's not as technically as you would probably hope, but the Expose attribute is explained here:

Expose attribute documentation