I have a Grid control with 6 rows and 6 columns.
On the top row, I have a dropdown that can have two states. (New or Used)
When I'm in the New state, I have two controls. Yellow Control in Row 3, Col 1 and Red Control in Row 5, Col 1
When I'm in the Used State, I want to swap the locations of the controls so that Red Control occupies Row 3, Col 1 and Yellow control occupies Row 5, Col 1.
Is this possible in Silverlight?
What you really want is the WPF triggers. Unfortunately, triggers are not supported in Silverlight, so that's not an option for you.
You could try the VisualStateManager class. Granted, its main purpose it to maintain transitions between visual states of the control, and thus it uses story boards and does anymation of the properties; hence, it might not work with the Grid.Column property.
Tim Heuer has a short introduction of VSM. Here's an opinion on the shortcomings of VSM.
You can also build you custom state manager on top of the VSM, which can give you state management without animated transitions and also potential support for properties not supported by the VSM class.
Or you could just have your own method that you call when the state is changed (you should know when that happens) and explicitly change the Grid.Column property on the two controls. The main drawback is that your code now has explicit knowledge about the visual representation and the layout and how it is tied to the state.
For that you can use the SetValue method.
You can do that on the event handler of the dropdown as follow:
_rowPanel1 = 2;
_rowPanel2 = 1;
panel1.SetValue(Grid.RowProperty, _rowPanel1);
panel2.SetValue(Grid.RowProperty, _rowPanel2);
Going further you could bind the Grid.RowProperty (and/or column) on the panel to
a clr property of a class that implements INotifyPropertyChanged.
Actually, the Grid class contains methods like:
Grid.SetRow(controlName, row_position);
Grid.SetColumn(controlName, col_position);
Grid.SetColumnSpan(controName, integer);
that I was able to use to swap my controls.
This works OK, because I only have one Grid in my control, however, I don't think that this would work if my control had multiple grids.
Add a Grid to the cells that need dynamic content. Add a method to handle dropdown selected item changed event. When it changes, dynamically clear then set the contents of the grids in their respective cells like so:
myContainerGrid.Children.Clear();
myContainerGrid.Children.Add(myNewControl);
If the content is more complex, you can wrap each up into a separate user control and dynamically load it into the container grid.
--Matt
Related
I have a StackPanel of Datagrids that contain data about various things. A user should be able to click on one of those datagrids and that datagrid should expand and take the place of the four datagrids on the screen. Clicking on the expanded grid should return the screen back to the previous display of four data grids.
I have tried replacing the top grid in the backend (I don't think this is a violation of MVVM since it is dealing purely with the display, but I could be wrong) with the selected grid, which doesn't seem to work. I have also tried hiding the grids to see if that would work. I found several topics here and elsewhere talking about moving columns and/or rows around at runtime, but nothing about moving an entire datagrid at runtime.
I would suggest building your UI view as a grid with column/row sizes bound to match their content, and use a backend property to determine whether the various datagrids should be Visible or Collapsed as a result of your clicking. Then the UI will adapt to fit the scenario you want.
Another alternative is to have a couple of views which have the explicit arrangement of controls you want, then have an outer ContentControl whose Content property is changed to one or the other as a result of the clicks.
I'd favour the former though for simplicity if feasible in your layout.
Learning WebForms here. Usually code for WinForms.
I have a need to write a stack panel that accepts custom class as rows. In Winforms I would make a custom class inheriting Panel that would tell each new control added to its control collection the location.y and width.x and it should appear immediately under the previous control.
The type of incoming row controls would be of a number of other custom Panel classes, each with their own set of controls (buttons, drop downs. text, etc). That is, the incoming rows do not follow a consistent template (though the number or unique types for rows is only 2 or 3). The operation of the app would decided what type of row goes in next.
How would I do this in WebForms?
An example of a custom class derived from Panel and how to use it in markup might be all I need.
It sounds like you want the ASP.NET AJAX Accordion control.
I am looking to create a windows form. This form is to display groups of data separately and I was aiming to do so in the same form window rather than have multiple windows open.
For example each group of data is defined by a Job#. A user will want to review X different Job#'s at a time (Range would usually be 1-5, but could be more). I would like to have 4 dataGridViews for each Job# plus various identifying and summed data in text boxes. Initial Example Concept
I was looking into using TabPages/Tab Controls. My initial idea was to have a user click the different tabs to view the data for those jobs that they have pre-selected. However these tabs don't seem to behave like classes from what I can see. Is there perhaps a better way to go about this or some way to have the tabs act like classes? So that each tab has a Job TextBox, 4 Different DataGridViews, etc. So that I can easily create and display any number of jobs?
For example each Tab would have 4 dataGridViews, maybe 8 Text Boxes, Standardized Labels and a Standardized layout.
So would using tabs be a good idea? Using some other WinForm control?
There are at least 2 solutions here:
Create a custom Panel holding all the controls you want (TextBox, DataGridView, ...), design it so that it looks best to you. Then add each of that Panel to each of TabPage of your TabControl.
Create a new custom TabPage and add the custom TabPage to your TabControl.TabPages instead of the standard TabPage.
I think the second approach can be done if you can initialize everything using code (not by drag-n-drop) because to get the drag-n-drop supported, you may need to write a custom TabControl. So the first approach is feasible and OK. You can replace the Panel by a Form, set the Form.TopLevel = false, you can add that form to any container control. Using Form, you can benefit the easiness of drag-n-drop to design and organize your controls.
Here is a little of code which may help you figure out:
public class TabPageClient : Form {
public TabPageClient(){
InitializeComponent();
Dock = DockStyle.Fill;
TopLevel = false;
FormBorderStyle = FormBorderStyle.None;
}
//.... other code
//I think this is important
//You should define some Properties and methods to control the data flowing into and out from your TabPageClient.
//You can also support some method to add/remove the controls dynamically.
}
Take the drag-n-drop requirement into account, I think using UserControl may be better:
public class TabPageClient : UserControl {
public TabPageClient(){
InitializeComponent();
Dock = DockStyle.Fill;
}
}
For UserControl, you should place the class in a separate *.cs file, compile your project and then you can see it in the ToolBox window (at the very top). Just drag and drop it like as other controls.
Personally, I prefer grid-detail views. Something we make heavy use of in our software. The form has a SplitContainer in vertical alignment.
In the top panel, you add a list of some kind (ListBox, ListView, DataGridView...any control into which you can load a list and then react to selection).
In the bottom panel, you have yet more options. Simplistically, you could use a TableLayoutPanel and then setup rows/columns to provide whatever arrangement of embedded controls you like, such as your array of grids to display data. I suppose in keeping with your model, you'd have a single ColumnStyle and four (4) RowStyles. Then in each row, add a grid.
This way, you keep it all in one place...one "screen", if you like (no tabs to flip through). You react to the selection in the list to decide what data to display in the grids. You then just need a bit of code (a class I would hope) that interfaces between the class(es) that provide the data, and the form controls that display it (the grids).
An additional benefit here is that with the list presentation, you can have a lot more than five (5) jobs in play at any one time. In fact, with scrolling, as many as you like (not limited to the number of tabs before the display goes to pot).
Also, you would be re-using the grids. Simply refreshing the displayed data for the list item selected. You could even pre-load and cache it all if freshness is not an issue.
Also consider binding directly to data source if that's an option.
I'm new in WPF and I need to group many components in one element and make and add new instance of that element in window for each student in database like 2 textblock plus 1 textbox for each student, how can i do something like that?
This is where WPF really shines - you can use an ItemTemplate or a DataTemplate to style the UI with the underlying data objects knowing absolutely nothing about how they are being presented.
Check out Data Templating for an introduction. Effectively an ItemTemplate is a template (definition) of how each item should be rendered. A DataTemplate goes a step further and gives you the ability to select which template to use based on the data item being bound to, so you can have a list containing different types of objects yet still show them all in the same list/repeater control on the screen.
Ultimately, my aim is to have a grid (by grid I mean rows and columns, however it's achieved) of small stack panels to represent time intervals throughout a day. Not too disimilar from the following I suppose (simple calendar-type layout on the right):
(source: msdn.com)
I need a way of creating this grid dynamically and naming the panels appropriately for whenever an event is fired (to be specific - a drop event, each panel's drop event will be wired to the same method in which I must distinguish what panel (i.e. at what point in the day, and on what row) the item was dropped on).
Thanks a LOT for any help!
Dan
You probably won't get the full code to do that from here, but I can point you in the right direction.
You are probably going to want to use nested ItemsControl. I have done something like this in the past where my outer ItemsControl for the Calendar was a Grid, and grid cell contained an inner ItemsControl with a StackPanel of TaskItems.
The most important part is getting your data layer right. I used CalendarDayModel classes, which had a Date property and an ObservableCollection<TaskModel> list. It also had Commands to handle user events, such as double-click events.
My outer ItemsControl was bound to the ObservableCollection<CalendarDayModel> and the inner ItemsControl were bound to the ObservableCollection<TaskModel>
I have some examples of an ItemsControl here, but take note of the last example that uses a Grid.