I am currently developing a C# WPF project. The solution has two projects, one called GUI which contains all the Windows and GUI controls of the program and a second project called coding which contains all the classes and logic to ensure that if I change the logic, it doesn't affect the working of the GUI.
In the GUI project I have added a reference to the coding project and said using Coding, and this allows me to access the logic classes from the GUI screens.
However, if in the Coding logic class project I want to load a new window from the GUI project how do I go about doing this. If I try and add a reference to the GUI project from the coding project it says that this can't be done as it creates a circular dependency.
How can I reference both the projects together so that GUI can access logic classes from the coding project and reference the gui project from the coding project so the coding logic class can open a new window from the gui project.
Thanks for any help you can provide.
You can decouple it by introducing the third project Common and move out Window and other shared classes into it. Then Gui and Coding projects can easily reference Common.
BTW, try to rethink your design because I'm worried that Coding project is aware of UI entities.
EDIT:
In WPF you can decouple UI stuff from a logic by using Commands, see whether yu can achieve this.
When we talk about WPF and SOC "Seperation of Concerns" , this lead us directly to MVVM , here a simple explanation
Related
I have a WPF project (already fully done). I'm going to make this project for mac. I would like to utilize my WPF project backend code as much as possible. But I couldn't find any option to reuse my WPF viewmodels in my Xamarin.Mac project.
The main problem appears to be that, in order to interact with Cocoa data bindings, the viewmodels must inherit from NSObject, use the Register annotation to expose the properties, and use the WillChangeValue/DidChangeValue methods for notifying observers. But in my WPF project, I used implementing INotifyPropertyChanged for the data binding if I'm not wrong.
Can anyone suggest how can I reuse my viewmodels efficiently? Any solution or idea would be good for me.
I got a question that almost asked by 3 years earlier. But couldn't get any specific solution idea. Please check it here.
I have a 'window forms application' project and it has a reference to class library lets say LibA. Now LibA wants to access some data of this 'window forms application' project, how to do it now ? I cant add reference of this 'window forms application' project to LibA because of cylic dependency thing.
You can not do both things referring LibA in 'window forms application' and referring 'window forms application' in LibA. You can add reference in one way only.
If you are in such a situation that means your project architecture is not well designed. So to over come this situation you should design it in such a manner so that you don't face this situation.
More over you can refer below link in which Cyclic Dependency and how to over come it has been explained very well
What is Circular dependency and how do we resolve it
A Class library should never reference a Windows Forms (an application level proejct)
The issue you're facing is related to software design (or software architecture)
If the class library needs something from the Windows Forms it means that the windows forms project is doing something it is not responsible for.
You have two solutions and both imply redesign
Pass the code from the windows forms to your class library
or
Create a new class library project, put the 'common' code there and reference it in both projects
I strongly advise you to read about system architecture
SOLID Design
Multitier applications. an example with asp.net
EDIT
Nevertheless, if you are aware of its dangerous, you could reference the windows forms dll itself from the output bin directory instead of the Project. Attention that is very bad code and done only in extremely rare cases.
Second choice, also not recommended, is to use reflection to access the windows forms dll. You can use Assembly.Load() and then invoke or get property values in run-time.
Given your (perhaps) level of expertise i'd strongly maintain the recommendation of learning more about system architecture.
Here's quick and dirty a trick to bypass cyclic dependency issues (nevertheless, I agree with SpiderCode to say that this should not happen with a good architecture).
In your assembly LibA, define:
public interface IMyUi
{
// put whatever functions you need to access from LibA
string GetData();
}
public static class MyUiProvider
{
public static IMyUi MyUi;
}
In your assembly LibB, just make the class you want implement IMyUi, and assign MyUiProvider.MyUi on program load
Once this is done, you can use your UI via MyUiProvider.MyUi.GetData().
NB: I put that as static to have quick example of the pattern. This might not be a good practice: static keeps your UI in gc roots, and it forbids you to have multiple instances... but you can transpose the idea to instance injection of the interface.
NB 2: this pattern is known as "inversion of control"
How can I expand the implementation of a wpf using my own custom classes? In particular, I want to create new C# classes on a wpf beyond the ones that derive from App.xaml and MainWindow.xaml. Should I add them directly on the project? If so, can I use references of the MainWindow elements inside them in order to tweak their functinality and add new tasks? Should they derive from the MainWindow class?
What is generally the most reasonable way to expand the implementation of a wpf to other new classes?
That is a rather broad question and where to place classes and from what classes to inherit are quite different problems. Both are ultimately a question of architecture though and what the right architecture for your application is cannot be answered here. It depends on what your application is supposed to do and how it should be done, all that should be planned out before doing anything with classes. You might want to read some smart book on topics such as software engineering and software architecture.
Ultimately you should get a good book on WPF, read it, and type all the examples into your editor. Simply trying to dive into an API with absolutely no example and no concept of how the architecture works is not going to get you anywhere very fast.
To answer your specific questions, though:
Should they derive from the MainWindow class?
No. To write the GUI for a WPF application, you rarely will have to use inheritance that isn't already written for you when Visual Studio generates a new app, a new window, or new user control.
It might make sense to use inheritance in your code somewhere, but rarely in the GUI code itself, and certainly not on the window or app level. The only manual use of inheritance will be for implementing custom WPF controls (the least frequent and most painful option for extending your GUI).
How can I expand the implementation of a wpf using my own custom classes?
It isn't clear what you're trying to do, so I'll try to cover all the cases.
UI
If you want a new application, usually you wouldn't derive from a specific application class at all, you'd just create a new WPF project (a whole program). Visual Studio will then create new classes for you that inherit from Application and Window.
If you want a new window, the same thing is true. You'd just tell Visual Studio to create a new window, and your classes would automatically be created for you, and they would inherit from Window.
If you want to add existing controls to a window, don't derive from anything. Go to the UI designer, and drag+drop controls from the Toolbox onto the page. Or edit the XAML for that window directly.
If you want to customize what happens when a user clicks on or works with a control, write event handlers for those controls. Or when you're comfortable about this, read up on data binding and the MVVM design pattern, since it will help you write cleaner programs.
If you're trying to customize the way your app or controls look, you'd usually use data templates, styles, user controls, and custom controls, in that order of frequency and difficulty. Except for custom controls, none of those involve manually written inheritance. When you add a User Control in WPF, Visual Studio will write a class that inherits from something, but you don't have to worry about that fact.
Non-UI
If you're trying to write the guts of your application, you probably should avoid writing any UI code.
It is a good practice to separate your UI from your main application guts. That way if a brand new technology comes out, you can strip off the UI, and throw the guts into a new program. Or if you decide to put those guts into a web page, that will also be possible.
You can reference this new code from the code-behind in the UI, or using the MVVM design pattern (which you should eventually read up on), but you should avoid mixing your UI specific code and your non-UI code as much as you can.
This means you won't inherit from any UI classes in order to implement the guts of your app.
I'm working with this small web application (1 page) built by someone else that does a specific task after pressing a button on the web page.
Now the requirements have changed slightly, and we need to automate this to run weekly without the need of user interaction.
What would be the best way of doing this, minimizing the changes done to the code?
I was thinking on adding a console app to the project that then references internally the web app but that doesnt seem to work.
Or maybe converting the web app to a to console app, if that is actualy possible?
Is there any straightforward way of doing this?
Thanks
First, make sure the "specific task" is broken out from the Web application so it resides in its own .NET project. Even if this project just contains one class you're "separating concerns" between the Web-based UI and the task itself.
Then you can create another "wrapper project" to call this new project as you wish. A console application might well do the job -- you can run that using a Scheduled Task -- or you may prefer to use a Windows service.
It really depends on how well the existing code is structured. A common approach is to divide business logic from the presentation layer. In VS, it's normally done by creating a class library project and keeping all the business logic in there. A web application project would then just instantiate business logic classes and run their methods.
If it is done like that, you just need to reference the class library project. If, on the other hand, you have all the logic in the web application project, probably there's no fast way of doing that, as you're not supposed to instantiate Page classes manually (well, you can do that as well, but that is clumsy and not recommended).
So in that case, you should create a class library project and move there all the logic you need to use in your console app. I would imagine that would require quite a bit of refactoring.
I've written a simple desktop application with C#/WPF and I'm now looking to create another, larger application which will share much of the functionality. I'm thinking that I should create three separate projects: one containing the shared code, and one each for the two apps.
My problem is that I'm not entirely familiar with .NET/WPF so I don't know if there are some best practices for this sort of thing. Can anyone offer some good sources of information, example projects or just some brief advice?
Edit: To put a little more detail on the scenario, the first application is a specialised editor and the second application is taking this file editor and wrapping a project model around it to create a sort of basic IDE.
Honestly it depends on what level the code you intend to share is. For instance, it's entirely plausable to put all of your business logic code into one project/class library and maintain it independantly, but mixing biz logic with WPF custom controls should be STRONGLY discouraged. Think about the layers of abstraction you are modularizing, and the dependancy heiarchy you are introducing and refactor accordingly.
Edit:
In response to your above changes I suggest the following: The logic and DAL associated with the above should be pushed into a project as seperate namespaces. The visual elements (the view, viewmodel) should most likely be moved into a seperate project and namespace set as well. Once you can merge these together and launch them from an exe that contains a host window and a UserControl for the rest of your hosted visual content, you can then probably move forward with integration into your larger IDE project. The key here is:
Visual Layer and View Logic -> Editor.Visual.dll
Biz Logic & Data Access -> Editor.Core.dll
I hope this helps.