I am using 14.2 for my wpf project. I want to have a window with a xamDataGrid in it and have that window reusable. I have 11 models. The window will show a given models task(which is data that needs maintenance). A model may have between 2 to 7 different data sources(derived from Linq to EntityFramework). The user will choose from a dropdown which table/task to edit in the grid.
Consistent behavior should be as follows:
So I understand I can create field layouts in XAML, however I am wondering if I can do the same thing in the code behind and have the behavior that is required?
Another question is; how do I toggle between the different layouts when I change the data source?
Hello:
I also have this issue, wherein I have several different slices of the data in different models and must display them in completely different column layouts.
My intention was to create several views one for each data model and simply make the inactive ones collapsed or hidden depending on say a DataTrigger. I'm very interested in what will be your ultimate solution.
Hi jerovsek,
An approach you can take for this would be to allow the XamDataGrid to automatically generate the FieldLayout for you. If AutoGenerateFields is set to true, it will look at your data and automatically create a FieldLayout for it. You can then handle the FieldLayoutInitialized event and use this to customize your Fields further. This would be the place to set whether a Field is editable or not, or whether it should be visible or not. In the Field.Settings object there is an AllowEdit property which you can set to enable/disable editing on the entire column. Controlling the Visibility is as simple as setting the Field.Visibility property.
Changing the background of a cell based on whether it is editable or not will require a new style for the CellValuePresenter control. You can create a DataTrigger in the Style.Triggers collection and bind the trigger to the CellValuePresenter.IsEditingAllowed property and change the background based on this.
<Style x:Key="NonEditableCellStyle" TargetType="{x:Type igDP:CellValuePresenter}"> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsEditingAllowed}" Value="False"> <Setter Property="Background" Value="Red"/> </DataTrigger> </Style.Triggers> </Style>
Using this style is as simple as setting the Field.Settings.CellValuePresenterStyle property:
Field myNonEditableField = e.FieldLayout.Fields["MyFieldName"]; myNonEditableField.Settings.AllowEdit = false; myNonEditableField.Settings.CellValuePresenterStyle = this.Resources["NonEditableCellStyle"] as Style;
With auto-generated field layouts, you don't have to worry about switching between layouts when the data source changes. When the data source changes, the XamDataGrid will look to see if it has any matching FieldLayouts for the properties inside the data source. If it doesn't find a complete match it will generate a field layout for you, at which point the FieldLayoutInitialized event will fire.
I hope this makes sense. Let me know if you have any questions.
That makes sense. I have worked with the winform grid so i was trying to find something equivalent to the InitializeLayout. thanks!
You're very welcome.
Yeah I went through the same logic... just didnt occur to use linq. thanks Rob!
Well, the Fields collection has a Contains method but that expects that you provide a Field object to check against. You probably want to see if a field exists by checking it's name though so that won't work. If you try to use the field name as the index of the Fields collection and the Field doesn't exist, that will produce an exception and we don't want that. So to avoid that you can use a LINQ statement which will return null if it can't find the Field.
Field f1 = e.FieldLayout.Fields.Where(f => f.Name == "MyField").FirstOrDefault();
Just replace "MyField" with the name of the field you are looking for and the result will either be that Field object or null.
Just wanted to be sure I was heading in the right direction. One more question comes to mind for this. How do I check to see if a field exists?
You have implemented this as I would have expected. Why are you concerned about needing to refresh the grid and what aspect would need to be refreshed? From the sample I can't see anything going wrong that a refresh would fix.