C# WPF >> send UI element value to rhino command

Hello everyone - this is a very general question but I’m stuck and am having trouble with the right approach to use.

I’ve been wrestling with using the output from a WPF UI element (ie. Slider) in a model (RhinoCommand) process. I understand simple events (ie. ValueChanged event) and how to catch the changed value (ie. double value = MySlider.Value) inside the simple, view model event, but I am extremely puzzled as to how to do this correctly when aiming to use the caught value in the underlying model.

I think a more advanced way of handling the event would be to use a control delegate but for the life of me, I have not been able to work out how to use one correctly. There might be other better practices. Below is my best attempt but it fails. As best I can tell the failure happens due to my inability to pass the slider object through to the model via the delegate command.

Any and all help or advice will be GREATLY appreciated.

public class Model: ViewModelBase
{
public DelegateCommand SliderCommand { get; set; }
private double slidervalue;
public double SliderValue { get; set; // with an INotifychanged not shown here }

public Model()
{
this.SliderComand = new DelegateCommand(OnSliderCommand);
}

private void OnSliderCommand(object sender)
{
*// sender always returns null so have not been able to use this to catch slider value*
}

} 
// end of Project class


// start of VM
public partial class MainWindow : Window 
{

public Model myModel { get; set; }

public MainWindow()
{
InitializeComponent();
mymodel = new Model();
this.DataContext = mymodel;
}

private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<Double> e)
{
var eventBinding = new EventBinding() { EventName = "ValueChanged" };
BindingOperations.SetBinding(eventBinding, EventBinding.CommandProperty, new Binding("DataContext.SliderCommand") { RelativeSource = new RelativeSource() { AncestorType = typeof(Slider) } });
 BindingOperations.SetBinding(eventBinding, EventBinding.CommandParameterProperty, new Binding());
}
// end of MainWindow partial class

slider XAML
\<Slider x:Name="MySlider" Minimum="0" Maximum="10" ValueChanged="Slider_ValueChanged"/>

Have you seen this? Here the different options are listed.

Maybe this will help.

You can bind a command to an event using the behaviors (old “interaction”) library. No need for Code Behind while using MVVM:

  xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
[...]
<Button>
         <i:Interaction.Triggers>
                    <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                        <i:InvokeCommandAction Command="{Binding StarterOnCommand}" />
                    </i:EventTrigger>
                    <i:EventTrigger EventName="PreviewMouseLeftButtonUp">
                        <i:InvokeCommandAction Command="{Binding StarterOffCommand}" />
                    </i:EventTrigger>
         </i:Interaction.Triggers>   
</Button>

You can also pass the event arg as command parameter. Therefore the command needs to allow this.

However, in our team we tend to write event-heavy dialogs in code-behind. But in any case, go for pure code behind or pure mvvm. Mixing both on one view is not great at all.

1 Like

I’ve been working with MVVM and WPF for 11+ years and using Sliders to make Model adjustments in our designs within Rhino successfully using MVVM and WPF.

Our UI is actually a separate application which communicates with our plugin to send the changes, however this would work fine if your UI was all in the plugin as well.

We’ve recently started using the new Microsoft Xaml Behaviors NuGet package suggested by TomTom. I highly recommend it, as it pulls all the old Blend SDK Behaviors, etc. into a single namespace / nuget package. Making it easier to setup Developer workstations.

Then you can simple catch the ValueChanged event on the Slider or at TomTom suggests the MouseUp event, and then call back to Rhino to do your work with the new value.

You could also setup TwoWay Bindings to your ViewModel so that as the slider is moved, your VM is updated, however trying to handle calls to Rhino in the Setter of your VM can cause other issues…