First of all i'm a newbie on MVVM pattern and C# / XAML developpment. Sorry for the inconveniant.
So the aim is to create a complete application including buttons, tabcontrol and use bindings and commands to gather them all correctly.
Each button represent a specific object which has its own information (name, id, serial number, ...). All these buttons are represented in a specific view which is on a top of the window. At the bottom of this window, i need to show a table with several items and content inside associated to the button pressed.
The problem here is the table. I need to display the information of the clicked object inside the table and the content inside can vary for all tabitems. And one other thing is that when one button in particulary is pressed, the view of the table totally change and display other information.
My questions are :
Do i need to create one model for each of my button / object AND an associated viewModel to it ?
The view including all of the buttons can be a separated view from the table and both of them will be in MainView ?
Can i represent data inside the table like a scrollviewer and is it possible to add new line wih other informations from the model when click on it ?
I hope my explanation is enough to helpor so here is a schematic representation of my application showing different context.
enter image description here
enter image description here
Thanks all of you for your help.
Do i need to create one model for each of my button / object AND an associated viewModel to it ?
You can go both ways. If your model communicates with different API and requires you to use different contract then yes use different models. Otherwise I would suggest using one. About ViewModel it is as well up to you it could be done both ways. I would suggest separation but as of in question I did not find any information about the size of the application itself so it all depends on the size and concern segragation.
The view including all of the buttons can be a separated view from the table and both of them will be in MainView?
You still need root view so everything should in the same view. I could suggest creating a new UserControl for each of the TabWindows then simply just collapse or make it visible depending on button command invoked.
Can i represent data inside the table like a scrollviewer and is it
possible to add new line wih other informations from the model when
click on it ?
You can add ScrollViewer into each of the tabs in TabControl. I am not quite sure what is the question on the second part of it but I would suggest to use ObservableCollection with ItemsSource to dynamically add items to your data table.
More information about MVVM pattern and its applications can be found here.
Related
I'm new to WPF and MVVM and attempting to write a firmware programmer so I can update stuff via USB and save and upload setting/state data. MVVM seems like it could work for this. I currently have pages and can navigate around the app (although the nav service is in code behind for now) but I'm stuck on how to implement things that aren't in the standard 'customer'/'person' examples.
On a couple of pages, there are subsections that I can see being sub-divided into separate views hosted in the page, and these subsections are used more than once in the app.
For instance, I want to have a TextBlock that displays the connection status and updates based on signposts in the connection process, firmware update, backup, etc. Progress bars with the % are another. Sections that are used to display errors, data or a selection box depending on what happens connecting would be another.
Having a sub-section house 3 completely different outputs all stacked on top of one another and shown based on the situation seems messy. I can see that section being a ViewBox and creating a unique view for each case being a better solution there (and possibly the other examples above).
Or take the 'status display', I can see implementing it as it's own view and the page's view model will use a messenger to pass the current status back to the 'status display' view model. I can also see it all just handled by the page's view model via calls to it's own methods. I can also see potentially using a global model to hold the status strings (maybe an enum?) and the view model can be made to pull the correct string into a 'currentStatus' variable.
What is the proper way to approach this? Keep it all a single page? Subdivide the dynamic/changing parts from the static parts?
OP:
Obviously the pages themselves are views, but would it be best to have the 'Status:'display TextBlock and it's value, and the Error/selector section be views also?
If you are asking whether the status and error displays should be UserControls then yes they can be "a view" irrespective of whether the control is using a view model or not.
Incidentally, it is generally better to use DependencyPropertys instead of view models in a UserControl otherwise you will end up having duplicate properties in both the view (so that MainWindow can databind to it) and in your control's view model (purely for the benefit of the user control).
If your UserControl uses DependencyPropertys then both users of the control and your view can both databind to the same set of properties without duplication. In this way you will realise that UserControls have no need for a separate VM.
OP:
...the page's view model will use a messenger to pass the current status back to the 'status display' view model...
Don't do this, this is what data binding is for.
I've recently built a Volley Scoreboard Application in Windows Forms that I'm trying to convert to WPF.
My first Window has all the controls to manage the game, while the second one is the window that will be projected on the big screen.
In Windows Forms I was able to update both labels (example, home_score on both Main and Projected) from a single point in code, but I don't seem to find a way to do this in WPF.
Any chance I'm missing something? Relatively new to WPF.
If it makes sense to have both pages (Views) utilizing the same View Model; which it sounds like it might given your use case, then the answer is simple:
Bind both labels (really, TextBlocks) to the same property. When the
property is updated; the binding engine will update both UIs.
If that isn't an option; the "master" View Model could invoke a method on the Model that would raise an event (ScoreUpdated). The "display" View Model would register for this event and update an appropriate property so that its View will pick up the change.
You need to:
to name the label (TextBlock Probably) in the xaml (Name="ScoreLabel")
keep a reference to the instance of the window.
after this:
otherWin.ScoreLabel.Text = "123";
I have a C# CLI program that scans for missing Windows updates and writes them to command line or serializes them to XML depending on the flag passed in. I'm trying to build a WPF component to this but am unsure of a few things. Specifically I'd like to write all missing updates to a grid in the center of my WPF main window. The appearance would be something like this (with gridlines between the fields):
NAME SEVERITY DETECTED
Security Update for Windows 7 (KB1234567) Important 3/9/2014
Security Update for Windows 7 (KB7654321) Critical 3/9/2014
My specific questions:
What type of control would I need to add to the window to house this data?
How do I send the data (detected missing update names and properties) to the grid for display?
How can I set the control so that it is collapsed (or invisible) when no missing updates are detected?
Will I need to add a scrollbar to the grid or will one display automatically?
Apologies for the simple questions. I'm really just looking for some examples to get started, and I haven't been able to find anything thus far that meets my needs.
What type of control would I need to add to the window to house this
data?
DataGrid control is what you are looking for.
How do I send the data (detected missing update names and properties)
to the grid for display?
Bind ItemsSourceof DataGrid to ObservableCollection<T> where T will be class containing data with properties Name, Severity and Detected.
How can I set the control so that it is collapsed (or invisible) when
no missing updates are detected?
Add a DataTrigger to check if ItemsSource collection contains no data, collapse the visibility.
Will I need to add a scrollbar to the grid or will one display
automatically?
DataGrid internally use ScrollViewer. No need to add explicitly.
Refer to the dataGrid samples here and here.
As an alternative DataGrid can offer ListView control, it will be little "easier" than the DataGrid, he also supports the ability to sort columns. For him also need to bind a ItemsSource collection to display:
The ListView control provides the infrastructure to display a set of data items in different layouts or views. For example, a user may want to display data items in a table and also to sort its columns.
Example in MSDN.
Little add some notes to the wonderful answer of #RohitVats, all that has been said about DataGrid also applies to ListView:
How can I set the control so that it is collapsed (or invisible) when no missing updates are detected?
In this situation, I advise you to adhere to the principle of MVVM. Use Binding and Commands to create an independent application. You want to create property (for example IsEnabled) in Model / ViewModel and use bindings to set them in the View, in order to avoid apply directly to the Control. WinForms style app or "regular" applications creates a strong connection between logic and UI, which subsequently impedes further change and application maintenance.
I'm writing a BHO that uses an ElementHost to host a WPF User Control. Within the user control, I have a DataGrid that binds to an Observable Collection. Everything functions fine, except that the content is not being read by screen readers (I'm using NVDA to test, but QA is using JAWS).
I'm restricted from copy & pasting code on a public forum, but I can describe the layout that I'm creating. There are two datagrid. One contains all of the items from the Observable Collection and the other is a subset of the items. Each datagrid is in a separate Tab Item of a TabControl. As I stated, there is an ObservableCollection that holds my business objects. Each object binds to a row in the datagrid. Several of the columns require that I display multiple properties from the business object, so I'm using the DataGridTemplateColumn. Within the CellStyle, I have 3 DataTemplates set up; one for edit, one for add and one for view. The view DataTemplate is exactly the same as the DataGridTemplateColumn.CellTemplate.
One of the columns holds my action buttons. One of the buttons is an edit button which simply applies the edit template to the rows cells. Outside of the datagrid, I have a button that will add a new default item to the ObservableCollection, call UpdateLayout on the datagrid, then set the DataTemplate of the new item to the add template.
There is also a button that will grab information from a remote server, convert it to business objects and add them to the Observable Collection. The datagrid loads the new information with no problems.
When I use the function to pull the objects from the database, none of the information will be read by the screen reader. If I click the edit button, everything is read as expected. After returning to the "view" DataTemplate, everything reads as expected. If I use the Add button, everything reads as expected.
To make this more complicated, if I edit an item in one tab page and get it to be read, then go to the other tab page and come back, it's no longer reading.
I have a feeling that it's related to the how binding and templates interact, but I don't know enough about either to figure out a direction to go in resolving this.
Any help would be appreciated.
EDIT: While I was creating the dummy project to show the issue, I discovered that the problem is not just limited to Template Columns. I created a business object with string properties, created an ObservableCollection with 10 objects in it and bound each property to a DataGridTextColumn, and it only reads the grid name and column index...the contents are never read.
I'm working on an app which encodes text to QR codes.
Currently I have a form which does this for a single string.
(source: fotopocket.nl)
At the top I've added a View menu item with two subitems:
Single (which is what we're looking at now)
Bulk (which would allow a user to select an import file)
When the user selects Bulk I want to have a different toolstrip and input fields (but the same menu).
Should I create another form for this with the same dimensions (and menu) and switch the forms when another view is selected.
Or should I code both views in the same form somehow?
Basically I don't want to let the user notice a complete new screen is loaded.
So if I would have to go the 2 forms route I need to make sure the forms will be placed at the same position.
What would be the correct way to get this functionality?
I would suggest creating a UserControl for the content (toolstrip and input fields) for Single and another UserControl for the content (toolstrip and input fields) for Bulk. You could add both to your single form and then show the correct one based on which menu option is selected.
This would give you some of the benefit of having two forms - your event handlers and such would be separated into each UserControl, but you would be loading the content into one user-visible form.