Merlin
Merlin

Reputation: 1

Pass parameter to UserControl viewmodel

I'm writing a monitoring program for a test rig. I'm using Prism and try to maintain good MVVM practice. However, I find it really hard to find a solution for my problem:

I have a service that receives measurement values from different sensors periodically. It passes the values with unique ids for each sensor to the data class.

The data class is the backbone of my program. It maintains a list with the last measurement of each sensor, updates their values and notifies value changes. It's a static class so every class has access to it.

//Rudimentary version of my data class, static and backbone of app.
public static class Data
{
    // Event signaling the change of a measurement, includes modified id in event
    #region event
    public static event EventHandler<MeasurementChangedEventArgs> MeasurementChanged;
    static void OnMeasurementChanged(MeasurementChangedEventArgs e) { MeasurementChanged?.Invoke(typeof(Data), e); }
    #endregion

    // List with custom measurement object containing multiple properties (e.g. Name, Value, Unit)
    private static List<Measurement> measurements = new List<Measurement>();

    // Used by server to set values
    public static void SetMeasurementValue(int id, float value)
    {
        // Get entry(s)
        IEnumerable<Measurement> data = measurements.Where(p => p.ID == id);

        if (0 < data.Count())
        {
            // Set value
            foreach (var item in data) { item.Value = value; }

            // Signal change
            OnMeasurementChanged(new MeasurementChangedEventArgs { id = id });
        }
    }
}

The ui is rather complex. It displays all sensor values, many in different representations. To make it easier for the developer to expand the program, I created UserControls e.g. a group of labels displaying name, value and unit of a sensor. I want to reuse these so I dont have to create them for every sensor. Here is how I#M doing it currently: The UserControl VIEW binds to variables like name, value and unit of the VIEWMODEL. The VIEWMODEL subscribes to the MeasurementChanged event of the data class. To know what sensor to display the VIEWMODEL need to know what sensor I want to display when I place a UserControl in the visual studio ui editor.

How do I tell the VIEWMODEL what sensor it should display, in xaml, when I place the UserControl in the visual studio ui editor?

Thanks!

EDIT 1 11.03:

I already researched a lot but can't find a solution that solves my problem. What I need is something like a dependency property (doesn't work because VIEWMODEL derives from BindableBase) or pass a constructor argument to the VIEMODEL in xaml (not really possible)...

Upvotes: 0

Views: 440

Answers (2)

SkyteamGorilla
SkyteamGorilla

Reputation: 21

You could use a PubSubEvent from the IEventAggregator to pass the information from your data class to your ViewModel.

Upvotes: 1

Andrea Cerfogli
Andrea Cerfogli

Reputation: 5

It seem to me that your question is on how to implement drag and drop in MVVM. I suggest you to add a reference in your project to GongSolutions.WPF.DragDrop.

then in xaml you can reference that package:

xmlns:dragDrop="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"

Add this property to the Dragsource (the element you drag from):

dragDrop:DragDrop.IsDragSource="True"

and these to the DropTarget (the element you drop to)

dragDrop:DragDrop.IsDropTarget="True"
dragDrop:DragDrop.DropHandler="{Binding}"

Your ViewModel should implement the IDropTarget interface:

public class M_ViewModel : BaseViewModel, IDropTarget

And define the following functions:

public void DragOver(IDropInfo dropInfo)
{

}

public void Drop(IDropInfo dropInfo)
{

}

Now you should be able to trigger the DropEvent in your viewmodel. About the information on which sensor the user selected, you can use the information from the selected element when you start the drag (maybe you have a list of elements, you can do a binding to the selected one and use that info). I did it that way, there may be a more elegant solution using DropInfo but I didn't research it.

Afterwards you give the parameter to the viewmodel of your usercontrol.

Upvotes: 0

Related Questions