wpf faulty class diagram, inheritance for userControls - c#

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.

Related

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: Unable to hit breakpoint on an inner class in my viewmodel

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.

Unable to inherit the class in C#

I have Capture class as follow:-
namespace FrontEnd
{
public partial class Capture : Window, DPFP.Capture.EventHandler
{
public Capture()
{
InitializeComponent();
}
protected virtual void init()
{
try
{
if (null != cap)
cap.EventHandler = this;
else
SetPrompt("Cannot Use the Device right now");
}
catch { MessageBox.Show("Cannot Use the Device right now"); }
}
}
}
I have Enrollment class as follow:-
namespace FrontEnd
{
public partial class Enrollment : Capture
{
protected override void init()
{
base.Init();
Enroller = new DPFP.Processing.Enrollment();
UpdateStatus();
}
}
}
I am getting three errors in Enrollment.cs:
1 - Partial declarations of 'Enrollment' must not specify different base classes.
2 - 'Enrollment.init()': No suitable method found to override.
3 - The name 'UpdateStatus' does not exist in current context.
I dont know where the problem exactly lies. Perhaps it is in the inheritance. Moreover, i am using WPF, so it might be possible that i am supposed to change xaml code as well in order to undergo inheritance.
Kindly help in resolving these errors.
I am pretty sure that like JAVA, multiple inheritance is also not allowed in C# as well. And for the class Capture you are inheriting from two classes.
public partial class Capture : Window, DPFP.Capture.EventHandler
There can be a work around for that. You can use multilevel inheritance. That will resolve the issue.
1 - Partial declarations of 'Enrollment' must not specify different base classes.
My first guess on this case would be, that you have another class that is also partial and derives from a different class than Capture.
2 - 'Enrollment.init()': No suitable method found to override.
The problem here is, that the base classes Capture, Window and Eventhandler do not define the init() method so you cannot override it. If you remove the override from the init method you should be good to go.
Probably the issue is a simple typo. In this method you call a Init() method and the override is a lower case init
3 - The name 'UpdateStatus' does not exist in current context.
Same issue like in 2. There is no UpdateStatus in the base class.
I also think, that it is an issue to derive from multiple classes becaus like java , c# does not support multiple inheritance.
Somewhere else in your code you have another class called FrontEnd.Enrollment. This will derive from something other than Capture. This is causing error 1.
Because the compiler cannot tell what the correct base class is you will not be able to resolve any members of that class. This is causing errors 2 & 3
So correct the issue with the multiple base classes and you'll be fine.

How manage a large interface for a WinForms application?

When thinking of the SRP, I find that an application that I'm writing is getting out of hand for our main interface/form. I'd like to change it before we get too far into the project.
What are some techniques for making a large interface that has a "drawing surface" with toolbars, menus etc? I'd also like it to be easy for this form to be testable. Should there be other classes that know how to control the MainForm such as a ChangedStateTracker (to monitor dirty state), DocumentCreator or something along those lines to "File > New" a new document?
The problem that I'm running into is there are so many methods inside the MainForm.cs and it's really starting to get ugly to maintain.
This can be marked CW if necessary. Any other hints/tips would be greatly appreciated.
If this is an option, I would create a set of user controls that together produce the entire form.
These separate user controls can then have their own responsibility and can be tested separately.
For the logic itself, create classes.
You can create classes like CreateDocumentCommand that implement some functionality. When e.g. the new document button/menu item is clicked, create an instance of this class and execute it.
public interface ICommand
{
bool CanExecute { get; }
void Execute();
}
public class SaveDocumentCommand : ICommand
{
public bool CanExecute
{
get
{
return MainForm.Instance.CurrentDocument.IsDirty;
}
}
public void Execute()
{
// Save your document here.
}
}
This by the way is how WPF does it.
Jeremy Miller has written about this a few times - these should get you started:
http://codebetter.com/blogs/jeremy.miller/articles/129546.aspx
http://www.jeremydmiller.com/ppatterns/default.aspx

Limiting access to inherited properties C#

Lets say I inherit a class, that has several public properties and/or methods, however I do not want them to be public properties/methods of my class - in other words, I want to make those properties protected properties of my class.
Can this be achieved?
I hope I was clear enough, if not please let me know, will try to explain myself better.
EDIT:
Right, thank you all for answers however I don't think I was clear enough. What I am trying to accomplish is this:
I wrote a windows control that extends ListView control. ListView has a public collection Items, that can be modified. That's all fine, however I wrote new methods for adding items to listview because of the extra data I need.
It all works great so far, however the Items collection can still be modified by anything, which is a problem, because if an item is added by direct manipulation of Items collection not all data I need is gathered, thus causing an error.
Since we hope to reuse this control several times in different projects, we are afraid that sooner or later, the default way of adding items to Items collection will be used (just a matter of time really). We are just looking for a way to prevent that from happening, like throwing an exception when Items collection gets bigger, but the way it was intended.
I hope this all makes sense now.
Never say never. This is probably not the best idea but it seems to work for me. This hides items by re-implementing it in the subclass and then hiding it using attributes. I added in a "CustomExposedItems" property so you can see that the existing items are still accessible in the underlying ListView.
public partial class CustomListView : ListView
{
public CustomListView()
{
InitializeComponent();
}
public System.Windows.Forms.ListView.ListViewItemCollection CustomExposedItems
{
get
{
return base.Items;
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("Use the new custom way of adding items xyz")]
public new System.Windows.Forms.ListView.ListViewItemCollection Items
{
get { throw new NotSupportedException(); }
}
}
Inheritance is all about saying "You can use this derived class in the same way as you can use the base class, and it provides specialized behaviour."
If you can't use the derived class in the same way as the base class, then you shouldn't be using inheritance: you're breaking Liskov's Substitutability Principle. In such a case, use composition instead of inheritance. (Personally I don't use class-to-class inheritance that much anyway, far preferring composition - I find there are relatively few cases where the specialization aspect really works without issues. When it does work it's great though!)
No, you cannot do that. The best you can do is creating a class and wrap the base class insted of deriving from it - but this will of course break inheritance. (I assume you cannot modify the base class. If you can, you should rethink the design because it looks like your new class should not derive from the base class.)
class BaseClass
{
public String IWantThis { get; set; }
public String IDoNotWantThis { get; set; }
}
class MyClass
{
private BaseClass baseClass = new BaseClass();
public String IWantThis
{
get { return this.baseClass.IWantThis; }
set { this.baseClass.IWantThis = value; }
}
}
You can't do this by inheritance. This is actually what inheritance is about. An is-a relation cannot reduce the interface. The derived class must be a full representation of the base class.
Turn your inheritance into a reference. You reuse the implementation of your "base class" by calling it. (Composition instead of inheritance.) If you need polymorphism, add a common interface or move the common part into a separate abstract base class.
I not use AOP, perhaps PostSharp, to put around the Property you don't want used, and then you can handle it in some appropriate fashion with your aspect.

Categories