Hi, I'm trying to create a visual representation of a vending machine layout so that the office can set up and change the product layout and the guy on the road can see the current layout as he's re-stocking it.It would have a fixed number or rows (shelves) but each row could have a different number of columns (product slots) depending on the size of the product.
My thought was for each slot be represented by a control with a picture of the current product and a combo box containing a list of products that we can stock it with, when we are setting up or changing the product in that slot.So in the app, if row 1 had eight squares representing 8 slots, row 2 might have 4 rectangles representing only 4 slots for larger products.
The WinDockManager looked like it might work for me, but before I really tunnel into that, I thought I'd ask if there was a more suitable control that I should try.
I would be grateful for any thoughts or opinions.
Do let me know if I've managed to post this in the wrong place.
Thanks
Pete
Hello Pete
Can you provide a mockup/illustrate demonstrating the behavior you desire?
From my understanding you are looking more for a grid-like control perhaps in CardView where each row is a card that lists fields with cell values.) If you want to suppress certain columns from appearing within a card you can collapse the field/cell's height manually. band.CardSettings.Style to VariableHeight
Thanks Michael,
Here is a very crude visualization of what I'm trying to do.The squares represent small products in the vending machine (single slots) and the rectangles represent larger products occupying double slots. I'd like to be able to show the product name, stock level and a small image, if possible and to be able to right click on a cell to access and change these properties.The vending machine configuration can change depending on product, so I want to be able to do things like merging / splitting the "cells", I suppose like a table in MS Word.Someone mentioned the GridBagLayout with regard to this project, but I haven't found any examples yet.Hope this image helps.Thanks again
Are the sizes of the items always integral? In other words... do you always have a small slot size and then a bigger slot size that is double (or some multiple) of that smallest size?
Are are the widths completely arbitrary? Could there be a slot that is 1.5 times the smallest slot?
Does the user need to be able to customize the slot sizes and configuration? Or just the contents of the slots?
Oh... the way you have it here in your example, the slots on each row are all the same size. Is that always the case that each row will always have a number of slots. Or could you have 2 small and 1 large item on the same row?
Thanks Mike,
That's great. I should hopefully get some time to really work on it this week. I'll certainly let you know if I get stuck, but I see where your ideas are going, so I'm pretty confident!.
Like I said, neither of these approaches will be trivial. Let me know if you get stuck and I will try to point you in the right direction. :) Just some things to keep in mind:
1) Use a BindingList<T> for the grid's DataSource and for the collection of slots on the row.
2) Make sure your class (T) implement INotifyPropertyChange so that the grid get notifications when a field in the data changes. You will want to do this both for the row and the slot object, so that your control can respond to the notifications, as well, and the row object will want to trap for notification in the slot objects and raise a notification when they change.
Well, if editing is not a big deal - or if you plan to edit the structure outside of the grid (or whatever control is visually representing it), then I would think this is definately doable using the WinGrid with either of the two approaches I mentioned.
The first approach, using a custom control for each row, and the UltraControlContainerEditor, would be simpler to code. All you need to a class that contains all of the information your custom control needs, which is essentally just a Bindinglist of VendingMachineSlots, and the integral width of the smallsest slot. Then the VendingMachineSlot just has to know what text to display and how many slots to fill.
You should use BindingList, because that has support for binding notifications when something changes. And your VendingMachineRow and VendingMachineSlot objects should both implement INotifyPropertyChange so that whenever you change a value, those notifications will bubble up to the BindingManager.
Mike, that was such a comprehensive answer, thanks so much for taking the time on this.
Yes, we would only display one machine at a time and would probably not really need to worry about drag drop or users editing the structure of the machine visually, too much, as we would likely do a refresh if they added to the row or column count.
It's reasonable to expect that layout changes should not be especially common after the initial setup, anyway. The visual representation of the current layout, stocks etc. and being able to access the stock properties of each slot is the important part here.I will look at your suggestions over the weekend and I'm sure I'll get this to work.I'll mark it as the answer and will reply, just to add a final note to say what worked best for me.Thanks again
Okay, so you basically have an integral width for each slot. And then every slots width is a multiple of that smallest width.
Also... you didn't answer my question about whether the user needs to modify the layout or if it's just something you, the developer create. I assume you probably want the users to be able to modify things.
To be honest, there's really no control in the Infragistics Winforms suite that's going to do this for you out of the box.
If it were me writing this application, what I would do is use the WinGrid. But you would have to use a lot of extensibililty to modify it to handle this kind of layout, because the WinGrid doesn't have the ability to merge cells within the same row like this - it has a fixed number of columns that apply to all rows.
There are a couple of approaches you could take to achieve that kind of cell merging. But none of them are trivial.
One approach would be to use the UltraWinGrid with a single column. That column would contain some object that contains all of the data for the entire row.
So imagine you have a VendingMachineRow object and you create a BindingList<VendingMachineRow> and bind that list to the grid. Then you have a VendingMachineSlot object, which has properties for name, capacity, image, ColumnSpan, etc. Each VendingMachineRow would have a BindingList<VendingMachineSlot>.
Then what I would do is create a custom control that essentially displays the entire row. This control would have a DataSource property that expects to be bound to a VendingMachineRow object, and when bound, it would create a number of UltraTextEditor controls that allow editing the various slots. You could use a single UltraTextEditor for each VendingMachineSlot or maybe even create a smaller custom control that handles editing the Name, capacity, and other properties of the slot individually.
Anyway, then you would hook it all up using the ControlContainerEditor to essentially embed your VendingMachineRow control in each cell of the grid.
Another approach would still require each row in the grid to have a single column, but instead of using a custom control embedded in each cell, you could achieve essentially the same thing using a CreationFilter to modify the UIElements of the cell. This is a slightly more difficult approach, but it uses a lot less memory, since it doesn't have to create a bunch of controls. I imagine memory is not a huge concern here, though, because I expect your application will only be showing one machine at a time, and expect it will not have more than a few rows - you probably won't have thousands or even hundreds of rows.
One tricky part of both of these implementation is editing. I'm not sure how you would deal with letting the user add a new slot to the row. Because if the row is already full and they want to add something new to it, it would have no room to display, so you'd have to reduce the width of some other item in the row. Presumably, you would want to use drag/drop, as well, which would also be very tricky with the first approach, but much easier with the second.