WPF: Unable to hit breakpoint on an inner class in my viewmodel - c#

I am currently working on a project that is requiring drag and drop functionality.
I am using the GongSolutions.DragDrop nuget package in order to simplify my solution. The library allows you to bind a "dd:DragDrop.DropHandler" attribute on the xaml to a class that implements the IDropTarget interface.
Inside my viewmodel I have created an inner class to implement this and have bounded to it as such, the functionality works but for some reason I am unable to hit any breakpoints within this inner class? I was able to hit all breakpoints when I had the viewmodel itself inherit from it but I decided to implement an innner class so I can have multiple drophandlers within it.
The following is the code with details removed for simplicity as there is a lot of code, breakpoints work inside the MainViewModel but when you set a breakpoint within ModuleItemsListDropHandler it will not hit the breakpoint at all
public class MainViewModel
{
ObservableCollection<ModuleItem> _moduleItems;
public ObservableCollection<ModuleItem> ModuleItems
{
get { return _moduleItems; }
}
ObservableCollection<ModuleItem> _moduleTiles;
public ObservableCollection<ModuleItem> ModuleTiles
{
get { return _moduleTiles; }
}
//breakpoints work within this method
public void addToList(MouseEventArgs e)
{
//removed for simplicity
}
public MainViewModel()
{
//removed for simplicity
}
//Class that will not let me hit breakpoints that are set
class ModuleItemsListDropHandler : IDropTarget
{
void IDropTarget.DragOver(IDropInfo dropInfo)
{
//functionality during drag over
}
void IDropTarget.Drop(IDropInfo dropInfo)
{
//functionality for drop
}
}
}
I am currently using the community edition of VS 2015

It's very unlikely that you have a class that just doesn't work with the debugger. Best bet is that the method isn't really being called. A quick call to System.Diagnostics.Trace.WriteLine() or even MessageBox.Show() can answer that question without much trouble.
However. Is this really how your drop handler class is defined?
public class MainViewModel
{
...
class ModuleItemsListDropHandler : IDropTarget
{
If so, that's a private class, so I wonder how you're binding an instance of it to anything in the XAML. You can't declare a non-private property with that return type, for example. You could be returning it as IDropTarget or as Object from something, of course.
Incidentally, classes (or anything defined directly in a namespace) ordinarily default to internal access, not private, but a child class, like a class member, defaults to private.

Related

How to connect two classes together

I am making a gallery tool that lets you browse and edit objects. I have a 'Library' class that manages the fetching and displaying of the gallery list. I also have an 'ActiveItem' asset that loads all the information of the selected object and deals with modifying it.
Now, there's some information that is stored in the 'library' class (for example the filepath) that I want to use in my activeitem.
I'm a bit confused as to how I can set this up efficiently.
I thought about embedding the activeitem class in the library class, but it gets a bit annoying to have to access all functions and properties of the activeitem through the library class (so instead of writing activeitem.Load() I would have to write lib.activeitem.Load() ). Activeitem already goes 4 levels deep and it's getting a bit much.
Are there other ways of setting this up? Can I store a reference of the library class instance inside the activeitem class, so that the activeitem class can fetch a property of the library instance?
Edit: added some code snippets
This are the class definitions:
class Library
{
...
public string LibDirectory;
...
}
class ActiveAsset
{
...
public SaveAsset()
{
//this method needs to know the LibDirectory property of the libraryclass
}
}
On initiating my winform, I initiate both classes:
Library lib = new Library();
ActiveAsset activeAsset = new ActiveAsset();
Given the concerns in the question comments, if you want ActiveAsset to be able to read information from Library you could change ActiveAsset's constructor to take in Library and store it internally as a private var.
class ActiveAsset
{
private Library _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
If you are worried about design and coupling you could make in interface for Library and then make the constructor use that instead of the Library class
interface ILibrary {
string LibDir { get; set; }
}
class Library : ILibrary {
}
class ActiveAsset
{
private ILibrary _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
As for performance and creating deep levels of nested classes I don't think you will have to worry so much about it, chances are you will hit data save/retrieve performance issues before anything like too many classes. That kind of performance design is only really important when you try to make you code work on small platforms where memory is limited like rasberryPi and such.
I would suggest creating a wrapper class which holds both the Library and the ActiveItem instances. Thus you can have more generalised methods like:
GetAllItems() - gets all items from the library
ActivateItem(Item item) - activates the item provided (stores the given item to a variable in the wrapper class)
etc. Think of that wrapper class as the manager of your application. You would only like to work with that manager regardless of what's beneath it.

WPF inheriting interface in view or in separate class

I'm making a media player program and I have the following interface:
public interface IMediaService
{
void Play();
}
Would it be more appropriate to inherit the interface in the view where the MediaElement control resides and access it directly in the implementation of the methods or rather have it in a separate class like this:
public class MediaPlayer : IMediaService
{
private MediaElement _mediaElement;
public MediaPlayer(MediaElement mediaElement)
{
_mediaElement = mediaElement;
}
public void Play()
{
_mediaElement.Play();
//...
}
}
vs inheriting it in the view:
public partial class MainWindow : IMediaService
{
public MainWindow()
{
InitializeComponent();
}
void IMediaService.Play()
{
Player.Play();
//..
}
}
I'm not using MVVM, but those methods might be used as bindings through commands.
The problem I see in the second approach is that my view class will get cluttered really fast.
I'm open to any alternative solutions that I haven't mentioned, this is just what I've come up with atm.
Would it be more appropriate to inherit the interface in the view where the MediaElement control resides and access it directly in the implementation of the methods or rather have it in a separate class like this:
It doesn't really matter as far as MVVM is concerned. There is no right or wrong really. It's depends on the developer's personal preference. If you don't want to pollute your view, you create a separate class. If you don't mind adding some methods to your view, you don't.
The benefit of using a seperate class is that you may reuse it for several different views/MediaElement.
But the view model only cares about the interface itself, i.e. it has no dependency upon the actual implementation of it.

wpf faulty class diagram, inheritance for userControls

So, after some searching on stackoverflow and on google, I did find a few answers on my question but didn't know how to actually implement it for my own use. Which is why I will ask it again here.
Because of my inexperience with wpf combined with that I have never used anything closely resembling it, I made the mistake of going into creating a class diagram which now(maybe) has to be completely changed.
I wasn't sure of how I would go about creating custom blocks, but kind of mapped out the behaviour I needed.
close example of what I was trying to work towards
After realizing I made a mistake after finding out about userControls I tried implementing this into my project.
This is a test I made:
base class
namespace TestTest
{
public abstract partial class TestBase : UserControl
{
public TestBase()
{
InitializeComponent();
}
public virtual void doSomething()
{
Console.WriteLine("ITS WORKING");
}
}
}
Child class
namespace TestTest
{
public partial class TestExtend : TestBase
{
public TestExtend()
{
InitializeComponent();
}
}
}
after this I tried to add testExtended to a canvas but it gave the type error: testExtended is not a UIElement
class diagram (both UIStackBlock and UISideBlock inherit from UIBlock and UIBlock is free to inherit from anything)
I will still need the inheritance I created for filtering out certain blocks(mostly on UIOperations)
Now my real question is, how would I go about adding multiple xaml files and defining the look of them in there without getting in the way of the current inheritance hierarchy I have in place. Or is this even achievable?
Again, I know this is a duplicate.
You can either write DataTemplates that are adjusted per DataType.
Or, you could leave behind inheriting from UserControl(just Inherit from Control or ContentControl) and make each of them a custom control with its unique style and Template.

Hook to object instantiation

I'm wondering if there's a way to hook to an event whenever an object is instantiated.
If it doesn't, is there a way to retrieve the object to which an attribute is attached to when the attribute is instantiated?
What I want to do is give some of my classes a custom attribute and whenever a class with this attribute is instantiated, run some code for it.
Of course, I could simply place the code in each of those classes' constructor but that's a lot of copy and pasting and I could easily forget to copy that code into one or two classes. And of course, would be very convenient for end users as all they would have to do is add my attribute to their classes and not worry about remember to add that bit of code in their constructors.
I actually can't do a base class because all of those objects already have a base.
Thanks in advance.
Here's an example of what I'd like to do. Either use the attribute's constructor or have an event handler for object instantiation.
public class MySuperAttribute : Attribute
{
public MySuperAttribute()
{
//Something akin to this or the event in Global
Global.AddToList(this.TheTargetObject);
}
}
[MySuperAttribute]
public class MyLabel : System.Windows.Forms.Label
{
}
public static class Global
{
public static void AddToList(Object obj)
{
//Add the object to a list
}
//Some pseudo-hook into the instantiation of any object from the assembly
private void Assembly_ObjectInstantiated(Object obj)
{
if(obj.GetType().GetCustomAttributes(typeof(MySuperAttribute), true).Count != 0)
AddtoList(obj);
}
}
There is no easy way to hook object instantiation externally, maybe with some debugging API, and it has a good reason. It makes your code harder to maintain and understand for other people.
Attributes won't work, because the instance of an attribute is not actually created until it is required - via reflection, and an attribute is assigned to a type, not an instance.
But you may well put the code in a base class, and derive all other classes from it, although it is also not a good practice to pass half-initialized instance to other methods. If the class inherits from ContextBoundObject, you can assign a custom implementation of ProxyAttribute to it and override all operations on it.
If you can't create a common base class (when your types inherit from different types), you can always create the instance with a custom method like this one:
public static T Create<T>() where T : new()
{
var inst = new T();
Global.AddToList(inst);
return inst;
}
However, seeing as you inherit from form controls, their instantiation is probably controlled by the designer. I am afraid there is no perfect solution, in this case.

Extending WPF application

I've got a WPF MVVM application. One of my views has a user control that needs to be customizable for each installation. It's basically a sketch of the customers installation with some labels etc. bound to a viewmodel.
Now my problem is that this user control is different on each site/installation. One approach is to load the xaml from a file/database runtime using a xaml reader. This works but since my viewmodel is generic I have to bind to methods instead of properties and I can't load a xaml with objectdataprovider.
Currently I'm trying to see if MEF can be used so that I can create the user control as a plug-in. So what I'm looking for now is this:
how can I define a user control with view/view model that exports a contract for MEF
How can my parent view (in my wpf app) load the imported user control
Any tips are appreciated, or maybe someone has a different approach?
I suggest you look into Prism in combination with MEF. It has a notion of Modules (plug-ins in your case) and Regions (mechanism of dynamically loading views).
You will be able to export a view using a simple attribute:
[ViewExport(RegionName = RegionNames.MyRegion)]
public partial class MyView : UserControl {
public MyView() {
this.InitializeComponent();
}
[Import]
public MyViewModel ViewModel {
set { DataContext = value; }
}
}
[Export]
public class MyViewModel : ViewModelBase
[
...
}
And in your main application XAML you will be able to import the plugin's views like this:
<ContentControl Regions:RegionManager.RegionName="{x:Static Infrastructure:RegionNames.MyRegion}"/>
One thing I'd consider is the design where you need to install a custom View for each installation. Instead, I'd look to make that View more generic. This will make your design more simple in the long run. Plus, you are setting up for a maintenance nightmare with a different installation for every installed base.
It's a little difficult to tell from your description, but it sounds like the View is a collection of some kind of an object (some kind of drawing with a label or something). Therefore, I'd treat it as such.
I'd create a base abstract class that describes what every object that your View could show. Since I don't have more information, I'll call this thing a "DrawingObject" for lack of a better term. This class would hold all information common to all objects in your View. Note that ObservableItem is a class that implements INotifyPropertyChanged, and SetProperty sets the value in that base class and raises PropertyChanged.
abstract class DrawingObject : ObservableItem
{
Point mPosition;
public Point Position
{
get { return mPosition; }
set { SetProperty("Position", ref mPosition, value); }
}
String mLabelText;
public String LabelText
{
get { return mLabelText; }
set { SetProperty("LabelText", ref mLabelText, value); }
}
}
Then, derive more custom objects from that base class:
class Counter : DrawingObject
{
public Counter() : base()
{
}
}
Your ViewModel would then just have a collection of these objects, using the base class. The set may be private, because you will probably get the objects from someplace in the constructor (i.e. the database, or a flat file, or...)
class ViewModel : ObservableItem
{
public ViewModel() : base()
{
// Call something to populate DrawingObjects property
PopulateDrawingObjects();
}
ObservableCollection<DrawingObject> mDrawingObjects =
new ObservableCollection<DrawingObject>();
public ObservableCollection<DrawingObject> DrawingObjects
{
get { return mDrawingObjects; }
private set { mDrawingObjects = value; }
}
}
Then, your View would bind to this collection and draw them appropriately (I'll leave that as an exercise for the implementer).
One extension that I didn't show is that the DrawingObject may need to implement the appropriate serialization functionality.
Obviously, this is a rough sketch of the design, and may have a couple of errors (I did it from my head), but hopefully it's enough to go on.

Categories