I'm working with WPF and the MVVM pattern and I need to append elements to the window from the ViewModel. The scenario is: the user will have a collection of textbox simmulating fields of a table to insert products, and there'll be a button to add more rows. My problem is just to create a way to make this button works. How can I do that ?
Is there a better way to solve a problem like this ? Needing to add many entities at once adding rows to a table ?
Thanks in advance for your aid.
Use an ObservableCollection in your view model bound to an ItemsControl. On the button click event add a new object to the collection. The UI will be notified that another object has been added to the collection and render the new row.
Related
I am working on WPF application, I want create one user control that contain one grid with 5 columns and i want to repeat this control on WPF window form according to data fetched from database. It might be repeat one time or more than one.
the ItemsControl (or List) may help you here. You can bind the ItemsSource Property to your ViewModel IEnumerable Property where your DBEntries are stored.
With the ItemsControl.ItemTemplate Property you can define what DataTemplate is used for each Item of the Enumeration.
KR,
incureforce
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.
I'm trying to make a search application using a wpf and entity framework following mvvm design patterns. When you search for someone, I want the ListBox to dynamically hold as many datagrids, as the search shows up. The datagrid will hold information such as first and last name, as well as a profile picture. I am kind of new to wpfs and c# in general, but I was thinking that the datagrid with all its information would be its own xaml. Then somehow I could add that xaml to the listbox as many times as I needed to(depending on the number of search results). Any help would be much appreciated.
Easy one: ListBox.ItemTemplate. The DataGrid XAML goes in the item template.
The search results go in an ObservableCollection of your search result class. That collection will be a member of your viewmodel, and in XAML you'll bind the collection to ListBox.ItemsSource.
The ListBox will instantiate the ItemTemplate once for each item in the search results collection.
Don't forget to implement INotifyPropertyChanged on your viewmodel, and raise PropertyChanged when you replace the collection with a new one. Changes to the collection's contents aren't your problem: use an ObservableCollection and it'll raise its own notifications for adds and removes. The ListBox will subscribe to those notifications without being asked.
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 not really sure how to go about my problem. Not looking for complete code just help with in which direction i should go. Since its MVVM I don't want any codebehind... if possible...
From the db i get the size of the "grid" i should create, for example 2x3.
Now i wish to place an "item" in this grid that takes up one or more spots.
I'm currently trying to do this with a ItemsControl that contains a grid (i want a grid because i want to use ShowGridLines="True")
But how do I create a dynamic grid? Thought about using uniformgrid but that one doesn't have ShowGridLines...
Second problem (since i'm a mvvm noob) is selecting the a spot in the grid. The one you click will not be a problem. The problem is if the item you're trying to place takes up two spots. How do I know which spot is the one next to the one i'm clicking?
Any help is appreciated
Since you cant easily Bind the Row/Column definitions of a Grid, i suggest you to build a simple custom control, which inherits directly from Grid.
Here is my approach with 3 additional dependency properties:
int MyColumnCount
int MyRowCount
ObservableCollection MyChilds
the MyColumnCount/MyRowCount will be bound to Properties in the ViewModel, which you update, when you get the new values from the database. Also the ViewModel will provide a collection of FrameworkElements, which will be the items in the Grid and is bound to MyChilds.
You can create new Controls in the ViewModel and use the attached property of the Grid, to set the Position. For example:
TextBlock b = new TextBlock() { Text = "Hello World!" };
Grid.SetRow(b, <your position>);
Grid.SetColumn(b, <your position>);
Grid.SetColumnSpan(b, <your column span>);
MyChilds.Add(b);
In the PropertyChangedCallbacks of the new int properties, you modify the Row/Column definitions, according to the new values. The callback of the collection property registers a collection changed event on the new ObservableCollection and adds the new items to the Grid's children, on changing events.
Thats all you need for the dynamic grid changes.
To your second question:
This is quite easy. In the event you catch you will get the sender of the clicked item in the grid. The sender is mostly the direct clicked control. You can use the static Grid functions again, to calculate the position:
Grid.GetRow(item);
Grid.GetColumn(item);
Grid.GetColumnSpan(item);
With the total number of rows/columns of the grid (My...Count) you can calculate neighbor positions.
Jan