0

I am new in WPF and MVVM also. I'm searching for USB devices in my program. But if I connect a new device, it is required to restart program to became visible.

How to do it, that refresh immediately.

Currently I have in my class in which I search device this:

public List<Devices> devices = new List<Devices>();

    public void FindDevices() // spremeni v public bool da dobis feedback 
    {


        _deviceList = HidDevices.Enumerate(VendorID, ProductID).ToArray();

...     devices.Add(new Devices()
            {
                DeviceId = nod + 1,
                ManufacturerId = deviceManufacturerstring[nod],
                ProductId = deviceProductstring[nod],
                SerialNumberId = deviceSNstring[nod],
                HardwareVersionId = "test4",
                FirmwareVersionId = "test5",
                DateOfManufaturedId = "test6"

            });

On hole for loop I add device to List. I need for loop because I read some data from each device.

I later add this devices in List in ViewModel:

public class Windows1ViewModel : ViewModelBase
{
    public ObservableCollection<Devices> devfuck { get; protected set; }
    List<Devices> _devicelist;

    public List<Devices> Devices
    {
        get { return _devicelist; }
        set { _devicelist = value; }
    }

    public Windows1ViewModel()
    {

        USBmiddleware cs = new USBmiddleware();
        cs.FindDevices();


        devfuck = new ObservableCollection<Devices>();


        foreach (var item in cs.devices)
        {
            devfuck.Add(item);
        }

        List<Devices> keks = cs.devices;



        NotifyPropertyChanged("devfuck");
    }


    public List<Devices> lvdevices
    {
        get { return _devicelist; }
        set { _devicelist = value; }
    }

What to change? Where to add INotifyPropertyChanged? Or how to solve my problem? Please for help. Thanks!

My ViewModelBase

public class ViewModelBase : INotifyPropertyChanged, IDisposable
{


    protected ViewModelBase()
    {
    }



    #region DisplayName


    public virtual string DisplayName { get; protected set; }

    #endregion // DisplayName

    #region Debugging Aides


    [Conditional("DEBUG")]
    [DebuggerStepThrough]
    public void VerifyPropertyName(string propertyName)
    {
        // Verify that the property name matches a real,  
        // public, instance property on this object.
        if (TypeDescriptor.GetProperties(this)[propertyName] == null)
        {
            string msg = "Invalid property name: " + propertyName;

            if (this.ThrowOnInvalidPropertyName)
                throw new Exception(msg);
            else
                Debug.Fail(msg);
        }
    }


    protected virtual bool ThrowOnInvalidPropertyName { get; private set; }



    public event PropertyChangedEventHandler PropertyChanged;


    /// <param name="propertyName">The property that has a new value.</param>
    protected virtual void NotifyPropertyChanged(string propertyName)
    {
        this.VerifyPropertyName(propertyName);

        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }

    protected virtual void NotifyPropertyChangedAll(object inOjbect)
    {
        foreach (PropertyInfo pi in inOjbect.GetType().GetProperties())
        {
            NotifyPropertyChanged(pi.Name);
        }
    }
    public virtual void Refresh()
    {
        NotifyPropertyChangedAll(this);
    }



    public void Dispose()
    {
        this.OnDispose();
    }

    /// <summary>
    /// Child classes can override this method to perform 
    /// clean-up logic, such as removing event handlers.
    /// </summary>
    protected virtual void OnDispose()
    {
    }



    ~ViewModelBase()
    {
        string msg = string.Format("{0} ({1}) ({2}) Finalized", this.GetType().Name, this.DisplayName, this.GetHashCode());
        System.Diagnostics.Debug.WriteLine(msg);
    }


}
Anton Sizikov
  • 9,105
  • 1
  • 28
  • 39
Pukaai
  • 367
  • 1
  • 4
  • 14
  • I think your `devfuck` property needs to be a `Dependency Property` http://stackoverflow.com/questions/617312/what-is-a-dependency-property – Ralt Jul 02 '15 at 12:06
  • When `FindDevices()` is invoked? – Alex Sikilinda Jul 02 '15 at 12:09
  • Try Adding a timer which calls cs.FindDevices() ever how often you need the list to be refreshed. – Johan Jul 02 '15 at 12:12
  • Love that variable name :-) You could implement INotifyPropertyChanged or as @Ralt says use a dependency property which has property notifications built in. Use "propdp" to generate a code snippet in VS. – James Harcourt Jul 02 '15 at 12:14
  • Is possible to do with eventhandler? When new device is inserted? – Pukaai Jul 02 '15 at 12:19

2 Answers2

2

You can do it by using a timer which gets called ever so often (as needed). Of course it would be sexier if you could do this using event management...

Thankfully there is a way to do this :

var watcher = new ManagementEventWatcher();
var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE       EventType = 2");
watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
watcher.Query = query;
watcher.Start();

as stated here: Detecting USB drive insertion and removal using windows service and c#

You can then subscribe to the event and invoke your

FindDevices()

From there.

Community
  • 1
  • 1
Johan
  • 262
  • 1
  • 15
  • And how for remove event? Where is there any difference? – Pukaai Jul 02 '15 at 13:18
  • Now when I like to call FindDevice(), show error: "Error 2 No overload for method FindDevices' takes 0 arguments". What I must fix? – Pukaai Jul 02 '15 at 13:24
  • Sounds like you have changed your FindDevice() method and have added some properties that you pass to that method...if you have something like `public void FindDevice(string blahblah)` you can't pass it without that parameter – Johan Jul 02 '15 at 13:28
  • Alternatively you can make the the parameter optional by adding a default value `public void FindDevices(string bldsa="default")` – Johan Jul 02 '15 at 13:30
  • I add "object sender, EventArrivedEventArgs e", when I delete this then I have error in "new EventArrivedEventHandler(FindDevices);" ... Error is "Error 2 No overload for 'FindDevices' matches delegate 'System.Management.EventArrivedEventHandler'" – Pukaai Jul 02 '15 at 13:32
0

You need to implement the INotifyPropertyChanged interface in your Windows1ViewModel class. Then you need to call it from your property setter, or after you set the property as you are currently doing.

Next, you should set up a DispatcherTimer to call your FindDevices method every so often and then update the ObservableCollection property from there.

Sheridan
  • 68,826
  • 24
  • 143
  • 183