1

I plan on using something similar to this to detect when a device is plugged in. In short, it looks like I need to override WndProc.

Upon detecting the correct device, I want to add the files on the device to my application. The application has a "workspace" structure similar to VS. When the device is detected, I will add an ITreeView to my Workspace, and populate all of that child's children with the file names on the device.

The problem is, I'm not sure where to put this in my WPF MVVM application since OnSourceInitialized has to make a call to the base Window. Should I detect on a different thread with a hidden window? Should I just leave it in my MainWindow code-behind? Any suggestions are appreciated.

Kcvin
  • 5,073
  • 2
  • 32
  • 54

4 Answers4

3

I would leave it in MainWindow.xaml.cs. If you need to overwrite WndProc it's tightly related anyway and it belongs to some "system interface" which normally doesn't belong to your view-model or model. Also, there's nothing wrong with using code behind.

Well, it may be only a personal opinion.

JeffRSon
  • 10,404
  • 4
  • 26
  • 51
1

Second vote for code-behind here. There's nothing wrong w/ code-behind in MVVM if the code is strictly related to UI stuff. In this case, your model shouldn't care where or how you load the files, but rather just what it needs to do with it. IMHO, this is strictly a view concern, i.e. how you want the view to react when the USB drive is installed. If it were me, I'd have the code-behind call a method on the viewmodel or model to do the logic you need (sounds like viewmodel from what you're describing).

Joe
  • 1,295
  • 13
  • 16
0

MVVM is an abstraction from the general class of Presenter patterns that separate the view logic from the view by adapting the model to the view and using data binding. This abstraction also allows for fairly simple view concern testing. If you aren't able to separate the view from the model, or aren't testing, the MVVM abstraction isn't worth the trouble of maintaining it. You can use data binding just as easily from code behind.

Given those concepts and after reading the article you mentioned, I see nothing in the article about WndProc and OnSourceInitialized being required to enumerate usb drives, so I would do the standard thing and put that code in your model and create a view model and view specific bindings as appropriate.

Ritch Melton
  • 11,498
  • 4
  • 41
  • 54
  • 2
    To enumerate no; but to catch the `WM_DEVICECHANGE` Windows event, which detects the device added/removed event, I need to use `WndProc` and `OnSourceInitialized`. Unless I create a new thread and continuously use WMI queries which seems inefficient. – Kcvin Jun 28 '13 at 14:02
  • 1
    With events, background workers, and tasks there's usually no reason to create a thread directly in .Net. I'd be surprised if you couldn't make an event work as in this article: http://stackoverflow.com/questions/3772337/detect-when-drive-is-mounted-or-changes-state-wm-devicechange-for-wpf – Ritch Melton Jun 28 '13 at 14:29
  • FYI, I didn't downvote you. How else would I detect a device being connected? The easiest and most efficient (because it passes the drive letter, arrival/removal information, etc.) is to use the `Message` passed to `WndProc`. The other way being continuously querying by doing something like `DriveInfo.GetDrives();` which takes. Maybe there is a way to use `Rx`, but I'm not experienced with Rx. – Kcvin Jun 28 '13 at 14:31
  • Deleted last post, I stand corrected. @Ritch that is a good post as well. Thanks for your recommendation. I don't see your answer as being wrong. +1 – Kcvin Jun 28 '13 at 14:41
  • Cool. It seemed to me that hooking windows messages seemed a little too 90's. – Ritch Melton Jun 28 '13 at 14:52
0

I would start the process, say a timer, from the window and then dispatch back to the ViewModel with data and statuses which are bound to in the view.

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122