How to structure my project to use x:Bind - c#

After beeing used to structure my project in WPF on a light MVVM pattern, I'm looking into WINUI for a new project.
In the elapsed time, UWP and x:Bind did appear and it looks like the pattern can be much lighter. The whole concept of ViewModel has changed (maybe in a better way).
I'm looking for a "correct and maintainable" way to use x:Bind, to display Properties and call a function from a class.
In my App.xaml, I'm declaring a Configuration which contains all the sub-instances. Let's say a Camera. This Camera has an IP, and a method to call from the UI. What is the minimum code to be able to call and display those ?
For the moment, I have created a CameraView which is a UserControl. I have declared a public Camera object inside, which I can call and display but I don't see the way to affect this from my Configuration. This "link" between the view and the model.
Thank you for the help.

Of course there is a simpler way to implement MVVM: Microsoft itself shows how in its own samples, on GitHub.
However, to summarize it all, have a look at my answer in this question: How to pass data between pages
There I show, step after step, how to easily implement a working pattern to have a “shell” that holds all the app’s data.
Best regards

Related

How do I run a method from a relative ViewModel and get its return value?

To better show my problem, I drew a graph of how my ViewModel hierarchy looks like so far:
ViewModel hierarchy
What I want to achieve is simply call a method from ScriptEditorViewModel and ask it, if the object, which is currently being edited inside EditObjectViewModel has been specified in the script.
Later I also want to send some information to ScriptEditorViewModel and make it generate a script for the object if it doesn't exist.
ScriptEditorViewModel and ProjectManagementViewModel are 2 separate tabs in my program, which are basically operating at the same time.
Is it possible to do that and if so, is it a good approach?
Note: I'm currently using ReactiveUI as my MVVM framework but any other MVVM solution is also welcome.
When using MVVM pattern, you want to decouple components.
In View part there is xaml with bindings to data and command present in ViewModel.
In ViewModel you should keep data that is presented and logic that does something with that data. It is not the wisest thing to couple multiple ViewModels - keep their logic separated. If you have a command method, all data it deals with should be present in its ViewModel. For anything more complex, you shoud consider communicating with some kind of service or database.
Hence comes the Model part. Here you want to create the model of something you want to store and not necessary present in a View.
I don't know if I understood your problem well, but including a database or any kind of 'persistence layer' into your solution should resolve the problem of accessing specific information. You can create some in-memory storage for start.

Overusing code behind in my WPF application?

I'm creating a simple WPF application for practice purposes only, but I have little experience in WPF. Using WPF XAML seems troublesome to me, as I have a lot more experience with C# Console and especially with the C#- and JS-driven videogame engine Unity, where devs have access to an Editor (analogous to the Design Window in WPF) and the code behind, with no XAML whatsoever. This is why I tend to use less XAML and much code behind.
For example here, I modify the Margin property of a button, while I set its Opacity to 1; this all happens upon a click event to the grid, which calls the function (exactly the way it's done in Unity):
public void Grid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
RandomButton.Margin = new Thickness(0, 0, 0, 0);
RandomButton.Opacity = 1;
}
If I'm not mistaken, this can be achieved through Data Binding in XAML as well, although it seems to be a lot more complicated method seemingly producing the same result.
So my questions are: is there a difference between the two ways, say, performance-wise or in terms of expandability (which one would be easier to expand/modify later)? Which one is used in the industry?
There is no difference as far as the performance is concerned. For any element that you define in your XAML markup, an instance of a corresponding type will be created by the framework at runtime.
It is generally much easier to define the visual presentation of an application using XAML though. This is what XAML is used for after all: https://msdn.microsoft.com/en-us/library/cc295302.aspx
You still use a programming language such as C# to implement your application logic though, i.e. what happens when a mouse button is pressed etc. So setting/modifying the properties of any element that you originally create in the XAML markup using C# is fine.
Which one is used in the industry?
When it comes to enterprise WPF applications the recommended design pattern to use is MVVM (Model-View-ViewModel). You can refer to the following link for more information about it: https://msdn.microsoft.com/en-us/library/hh848246.aspx
The view is responsible for defining the structure, layout, and appearance of what the user sees on the screen and is typically created using only XAML whereas the view model and the model that are responsible for handling the view logic and business logic respectively is implemented using a programming language like C#.
You will find a lot more information and samples of how to implement the MVVM design pattern if you Google or Bing for it.
Hi being a WPF/XAML developer I would suggest you to use XAML as much as you can.Make use of commands and bindings i.e use MVVM architecture. What if you want to set the opacity using keys (example: ctrl+shift) you will have to write another code behind for that making your code redundant affecting performance of your app. Make use of MVVM pattern ( You can use MVVM light by galasoft). As of expanding or modification you will have to modify a single command method rather than modifying each event etc on the code behind. Easy to test ..Easy to build..Easy to modify..

How to integrate Windows.UI.Composition animations into UWP MVVM Light app

I’m utilizing the Windows.UI.Composition framework for the first time in my app. My app is built on MVVM Light. I'm updating the app to add more transition animations between elements.
The prevailing wisdom with MVVM is that you should keep your UI code in XAML as much as possible, binding visual states to the ViewModel properties, etc. But all of the Windows.UI.Composition material and samples I’ve been seeing, define the UI manipulations in the code-behind instead.
Let’s use a show/hide scenario as an example. I have a bool property in my ViewModel like ShowTheBox. I bind TheBox’s Visibility property to the ViewModel property. The Box will show or hide automatically based on changes in my ViewModel.
Now, using Windows.UI.Composition, I want to add fade-in/fadeout animations to the visibility changes of TheBox. Where is the best place to put that C# code and how do I bind that transition to my ShowTheBox property?
I wouldn't agree that point of MVVM is to keep UI code in XAML exclusively. The point of MVVM, as any other layer separation pattern, is to separate UI layer from app's logic. MVVM just adds its own flavors in form of bindings.
So I think that when you have complex animations and other UI related stuff, it's perfectly fine to put them in code-behind. But before doing that, you might want to try to extract as much of your animations as you can to custom controls which will facilitate your doubts a little.
EDIT:
Making a lot of your UI logic bound directly to ViewModel properties isn't always a good solution. Layer separation exists for a reason, so when you compose your layers, imaging that you're writing a Xamarin app and have common ViewModels, but different Views for different platforms. Now you're not even sure if on another platform is gonna have those animations or not. Maybe a flow that takes one screen on UWP will take two screens on iOS, or something else. To have a property "IsVisible" which serves only for one of many views isn't making much sense now, does it? So you have to find some common denomination for ViewModel and move everything else to UI layers.
At the end of the day, MVVM is just a pattern which helps you write a better code. It's understandable to want to stick to all the good practices as much as possible, but if it doesn't make sense for your app - is it worth it?

Correct application design: data reading and UserControls

this could be a long question, I'll do my best to ask it properly.
I want to read large .txt files with lots of numerical data. In each file there will be "channels" (30-50 channels, with own name, axis units, and of course, data). So I've created a class Channel with that properties, and a class File that has a list of that channels. It also has a method that reads the file and stores everything in lists.
I want to be able to load several files at the same time, and for that I've created a UserControl that consists in a button for loading the file and a ComboBox that displays each channel:
(The ComboBox is bound to an ObservableCollection)
The data is stored in the code behind of the user control. So when I insert in my MainWindow several UserControls I can't access that data.
What I want is have several UserControl...
...and be able to plot the data from each one in that Plotter, and be capable of some control (previous, next..)
My first approach was to store everything in the UserControl, that was easy to do but ineffective.
So what I figured out that might be the solution is to store everything in other place and then access to there from the MainWindow or other place. I've tried VERY HARD to learn MVVM and use it in my project. But I must be very STUPID because I can't get it.
My new approach is described in the next scheme:
My questions:
1.Is this the correct way of doing it? If the MVVM is the way, please, I beg you, please, guide me just a little bit in the beginning, because I am not capable to translate that intricate examples out there of MVVM to my project.
2.If I'm doing it more or less right, how could I store all that data in some other place and the access it from MainWindow? (in my File class I have a method that stores all in lists, so in my UserControl I have the "Browse" button that gets a filename, and then with the read() method I store everything inside (?) the File class, or at least inside the place I've created the new File: the UserControl).
I'll post code, pics, more info, anything if needed. Thanks.
If the MVVM is the way, please, I beg you, please, guide me just a little bit in the beginning, because I am not capable to translate that intricate examples out there of MVVM to my project.
You're already half-way to using something that's MVVM, at least in nature. It isn't "the way", but it would definitely be a (reasonably nice) way to handle this.
In order to design this with an MVVM type of design, you'd want to make your "MY DATA" class be the DataContext of the UserControl. All of the data would be stored there (preferrably in ObservableCollection<T> instead of List<T>, as that will handle binding more effectively).
Your "UserControl1" portion would likely be some form of ItemsControl, bound to a collection of sources. The selected item could then be bound to something on your "MY DATA" class, which determined which "plot" should be displayed.
To answer your questions directly:
1.Is this the correct way of doing it?
This is definitely a step in the right directly. Storing your data separate from your controls is one of the key pillars to making your application more flexible and maintainable (and a large goal of MVVM).
2.If I'm doing it more or less right, how could I store all that data in some other place and the access it from MainWindow?
You handle this by setting the class as the DataContext of your UserControl and/or MainWindow. This allows you to bind to properties on your data class (which is effectively your ViewModel in MVVM terminology).
Also, I know you've tried to study and learn MVVM - and it's difficult to grasp initially, but it is worth the effort. I will say that your design scenario (which is effectively a list of "options" on the left, and a "detail" pane on the right) is not an uncommon one - it's actually similar to my example in my blog series on MVVM, and should be fairly easy to create once you understand the basics.

Struggling to understand MVVM architecture

I'm trying to learn MVVM and WPF and I'm using the MVVM Light Toolkit. Here's what I'm not fully understanding and maybe it's due to an incorrect architecture of my UI.
What I'm trying to accomplish is pretty simple actually. This is a utility application by the way. I want a window that serves as the 'controller' so-to-say that has a set of buttons. Each button should change the content of a frame. Example: one button loads a 'screen' ( or a 'view' if you will ) that allows the user to configure an 'Agency' which is a custom object. Another button loads a list of Users from the Agency that was in the first 'screen'. This 'Users' view needs to also be loaded in the same frame. In fact, as of right now, the window with all the buttons really is only responsible for loading the 'screens' in the frame. The meat of the application will be within all the separate 'screens'
What I am not understanding is 1) how to let each screen/view know about each other since one is dependent upon the other. It seems that in MVVM the ViewModel shouldn't know about anything. But in my case, I need to pass information around ( such as my Agency ).
If I can get some hints on what I need to look into, that would be great.
Thanks!
Some ideas that might connect some of the dots:
You'll most likely have one viewmodel per view ("screen").
Each viewmodel will contain all of the logic for its corresponding view
Viewmodels can and will know about the models (Agency, Users)
Viewmodels can communicate with each other via the Messenger in MVVM Light
Think of MVVM Light's Messenger as an "application-wide eventing system". When you send a message out from one view model, any other view model can be listening for that message/event and react to it as needed.
Does that help at all? Keep your thoughts coming and I'll keep commenting and I'm sure the community will as well :)
Few things:
each of your screens, should be separate view (eg. user control or new window - I suppose you've done that already)
every part of model (eg. Agency, User) you want to display in your application, should be wrapped with its dedicated view model
your views don't really need to know about each other; you can use commands or events on view models to get rid of those dependencies
view model only needs to know about one thing: model it's building on
it's good to think about view as really simple class, with one single responsibility of rendering content; no logic, no code behind (unless it's purely UI/display related) is something to follow
You can try to prepare your models first (if you haven't done that already), then make view models for them (thinking what properties of models you want to expose to views) and once that's ready, build your views basing on view models. Other way around is also viable option - pick whichever feels more natural to you.
One more thing: since you mentioned you can display several screens in one (I assume) main area, think about equipping your view models with something along the lines of bool IsCurrentlyActive property. This way, you can easily show/hide views with button clicks and still utilize binding mechanism.
They shouldn't know about each other. That is what the Messenger is for controllers and views subscribe to the events they are interested in. That way they don't need to know or care where they event originated.
Hmm Kendrick is faster. What he said.
Also it sounds like you kind of want an Outlook type interface, some navigation that loads other views. I had the same question a while ago. How to do Regions in WPF without Prism?
To better understand the MVVM pattern look at this article: WPF Apps With The Model-View-ViewModel Design Pattern
Also I advice you to look at Caliburn Micro framework.

Categories