Skip to main content
Home Forums Silverlight Programming WCF RIA Services NET RIA & DataGrid Column Header
9 replies. Latest Post by bykinag on November 4, 2009.
(0)
bykinag
Member
137 points
51 Posts
07-15-2009 6:11 AM |
Proceeding from a paradigm net ria services:- How to receive names of fields for columns DataGrid, it is posible?- Why DataForm is able to load names of fields, and DataGrid is not present?Look an example (home.xaml): http://depositfiles.com/files/75io2he5q
Thanks for answers.
07-17-2009 4:41 AM |
UP
ColinBlair
Contributor
6741 points
1,318 Posts
07-17-2009 10:39 AM |
I know English isn't your first language, but I have no idea what you are asking.
07-17-2009 1:03 PM |
by using translate.google.ru
taking advantage of the NET RIA Services: - Why the DataGrid does not load the names of the columns, but it can DataForm? Ask not just because paradigm NET RIA Services states that it must be stored on the server, so as not to dilute the logic on the client and server, this is what I mean!
original of message:
используя возможности NET RIA Services:- почему DataGrid не загружает названия столбцов, а DataForm это умеет?Спрашиваю не просто так, т.к. парадигма NET RIA Services гласит о том, что все должно храниться на сервере, дабы не размывать логику по клиенту и серверу, вот о чем я!
narayans
38 points
19 Posts
07-17-2009 1:29 PM |
Hi there,
I think I understand you - as I had the same problem. When you have a DataGrid that is not set to AutoGenerate the Columns, it does not get the Header from the DisplayAttribute. This is quite annoying. I solved the problem by creating my own DataGrid that inherits from System.Windows.Controls.DataGrid and add the following code. I then call FixColumns in the DataSource Loaded event:
public class DataGrid : System.Windows.Controls.DataGrid { protected Type GetEntityType(DomainDataSource ds) { if (ds != null && ds.DomainContext != null) {
// I know this is a total hack... // Know a better way to get the entity attached to this DataGrid? Likely from the Binding Type dsType = ds.DomainContext.GetType(); MethodInfo mi = dsType.GetMethod(ds.QueryName + "Query", new Type[0]); if (mi.ReturnType.IsGenericType) { return mi.ReturnType.GetGenericArguments()[0]; } } return null; } public void FixColumns(DomainDataSource ds) { Type type = GetEntityType(ds); if (type == null) return; foreach (DataGridColumn column in this.Columns) { FixColumn(column, type, false); } } protected bool FixColumn(DataGridColumn column, Type itype, bool isAutoGenerated) { DataGridBoundColumn bc = column as DataGridBoundColumn; if (bc != null) { PropertyInfo pi = itype.GetProperty(bc.Binding.Path.Path); if (pi == null) return false; object[] disp = pi.GetCustomAttributes(typeof(DisplayAttribute), true); if (disp.Length > 0) { DisplayAttribute dispattr = disp[0] as DisplayAttribute; if (string.IsNullOrEmpty(bc.Header as string) && !string.IsNullOrEmpty(dispattr.Name)) { bc.Header = dispattr.Name; } } } return true; } }
// I know this is a total hack... // Know a better way to get the entity attached to this DataGrid? Likely from the Binding
07-18-2009 1:50 AM |
thanks for a code, it works fine.
08-22-2009 9:01 AM |
Hi,
Again me and my question:
How can i load column header for joined field in MyDomainService.metadata.cs
see my sample ("/Views/Home.xaml"): http://depositfiles.com/files/ds9nssec3
thanks.
11-03-2009 4:28 AM |
Below is the source DATAGRID Control, which allows to load Field Name Headers automatically from the model!
C# CODE OF DATAGRID CONTROL FOR GRABBING ALL HEADER NAMES: using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Linq;using System.Reflection;using System.Windows.Controls;using System.Windows.Data;namespace BusinessApplication1.Controls{ public class DataGrid : System.Windows.Controls.DataGrid { private bool IsFieldsHeaderGenerated = false; public DataGrid() { this.SelectionChanged += DataGrid_SelectionChanged; } void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { this.FixColumns(this.SelectedItem); } public void FixColumns(object record) { if (record != null) { if (!this.IsFieldsHeaderGenerated) { foreach (DataGridColumn column in this.Columns) { this.FixColumn(column, record); } this.IsFieldsHeaderGenerated = true; } } else { this.IsFieldsHeaderGenerated = false; } } protected bool FixColumn(DataGridColumn column, object record) { // THIS CODE TAKEN FROM Silverlight Toolkit => DataForm => GenerateFields() AND NOT MUCH CHANGED PropertyInfo[] propertyInfos = record.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); if (propertyInfos == null) { return false; } IDictionary<string, BindingMode> bindingModes = new Dictionary<string, BindingMode>(); foreach (PropertyInfo propertyInfo in propertyInfos) { if (propertyInfo.GetIndexParameters().Length > 0) { // Don't generate anything for indexed properties. continue; } if (propertyInfo.Name == (column as DataGridTextColumn).Binding.Path.Path) { DisplayAttribute displayAttribute = propertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true /* inherit */) .Cast<DisplayAttribute>() .FirstOrDefault(); bool propertyGenerated = false; if (displayAttribute == null || !displayAttribute.GetAutoGenerateField().HasValue || displayAttribute.GetAutoGenerateField().Value == true) { if (propertyInfo.GetSetMethod() != null) { bindingModes.Add(propertyInfo.Name, BindingMode.TwoWay); } else { bindingModes.Add(propertyInfo.Name, BindingMode.OneWay); } propertyGenerated = true; } if (propertyGenerated) { if (displayAttribute != null) { #region GetFieldName string name = displayAttribute.GetName(); if (string.IsNullOrEmpty(name)) { name = displayAttribute.GetShortName(); } if (!string.IsNullOrEmpty(name)) { column.Header = name; } #endregion } } if(column.Header == null) { column.Header = propertyInfo.Name; } } } return true; } }}
using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Linq;using System.Reflection;using System.Windows.Controls;using System.Windows.Data;namespace BusinessApplication1.Controls{ public class DataGrid : System.Windows.Controls.DataGrid { private bool IsFieldsHeaderGenerated = false; public DataGrid() { this.SelectionChanged += DataGrid_SelectionChanged; } void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { this.FixColumns(this.SelectedItem); } public void FixColumns(object record) { if (record != null) { if (!this.IsFieldsHeaderGenerated) { foreach (DataGridColumn column in this.Columns) { this.FixColumn(column, record); } this.IsFieldsHeaderGenerated = true; } } else { this.IsFieldsHeaderGenerated = false; } } protected bool FixColumn(DataGridColumn column, object record) {
// THIS CODE TAKEN FROM Silverlight Toolkit => DataForm => GenerateFields() AND NOT MUCH CHANGED
PropertyInfo[] propertyInfos = record.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); if (propertyInfos == null) { return false; } IDictionary<string, BindingMode> bindingModes = new Dictionary<string, BindingMode>(); foreach (PropertyInfo propertyInfo in propertyInfos) { if (propertyInfo.GetIndexParameters().Length > 0) { // Don't generate anything for indexed properties. continue; } if (propertyInfo.Name == (column as DataGridTextColumn).Binding.Path.Path) { DisplayAttribute displayAttribute = propertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true /* inherit */) .Cast<DisplayAttribute>() .FirstOrDefault(); bool propertyGenerated = false; if (displayAttribute == null || !displayAttribute.GetAutoGenerateField().HasValue || displayAttribute.GetAutoGenerateField().Value == true) { if (propertyInfo.GetSetMethod() != null) { bindingModes.Add(propertyInfo.Name, BindingMode.TwoWay); } else { bindingModes.Add(propertyInfo.Name, BindingMode.OneWay); } propertyGenerated = true; } if (propertyGenerated) { if (displayAttribute != null) { #region GetFieldName string name = displayAttribute.GetName(); if (string.IsNullOrEmpty(name)) { name = displayAttribute.GetShortName(); } if (!string.IsNullOrEmpty(name)) { column.Header = name; } #endregion } } if(column.Header == null) { column.Header = propertyInfo.Name; } } } return true; } }}
XAML CODE FOR USING: xmlns:appControls="clr-namespace:BusinessApplication1.Controls"...... <appControls:DataGrid x:Name="dataGrid" ItemsSource="{Binding ElementName=dds, Path=Data}" AutoGenerateColumns="False"> <appControls:DataGrid.Columns> <!-- THIS COLUMNS JUST FOR SAMPLE --> <data:DataGridTextColumn Binding="{Binding CustomerID}"/> <data:DataGridTextColumn Binding="{Binding ContactName}"/> <data:DataGridTextColumn Binding="{Binding ContactTitle}"/> <data:DataGridTextColumn Binding="{Binding CompanyName}"/> <data:DataGridTextColumn Binding="{Binding Country}"/> <data:DataGridTextColumn Binding="{Binding Region}"/> <data:DataGridTextColumn Binding="{Binding City}"/> <data:DataGridTextColumn Binding="{Binding Address}"/> <data:DataGridTextColumn Binding="{Binding PostalCode}"/> <data:DataGridTextColumn Binding="{Binding Phone}"/> <data:DataGridTextColumn Binding="{Binding Fax}"/> </appControls:DataGrid.Columns></appControls:DataGrid>
xmlns:appControls="clr-namespace:BusinessApplication1.Controls"......
<appControls:DataGrid x:Name="dataGrid" ItemsSource="{Binding ElementName=dds, Path=Data}" AutoGenerateColumns="False"> <appControls:DataGrid.Columns> <!-- THIS COLUMNS JUST FOR SAMPLE --> <data:DataGridTextColumn Binding="{Binding CustomerID}"/> <data:DataGridTextColumn Binding="{Binding ContactName}"/> <data:DataGridTextColumn Binding="{Binding ContactTitle}"/> <data:DataGridTextColumn Binding="{Binding CompanyName}"/> <data:DataGridTextColumn Binding="{Binding Country}"/> <data:DataGridTextColumn Binding="{Binding Region}"/> <data:DataGridTextColumn Binding="{Binding City}"/> <data:DataGridTextColumn Binding="{Binding Address}"/> <data:DataGridTextColumn Binding="{Binding PostalCode}"/> <data:DataGridTextColumn Binding="{Binding Phone}"/> <data:DataGridTextColumn Binding="{Binding Fax}"/> </appControls:DataGrid.Columns></appControls:DataGrid>
Do not forget to write the attribute Display(Name = "YOUR_FIELD_NAME") on the field this model class file YOUR_DomainService.metadata.cs
Sample how to using
Enjoy and be Happy :)
Casimodo72
301 points
159 Posts
11-04-2009 7:20 AM |
Bykinag, thanks for the code, but I would rather prefer a solution similar to narayans' because your solution does not work when the grid is empty; i.e. when there are no entity *instances* to extract the column headers from. Narayans' solution operates on the *type* into of an entity.
In my opinion the current implementation of the DataForm is even more improvable than the DataGrid's: the DataForm just refuses to display any content when it is empty; i.e. when its CurrentItem is null it disappears.
Regards,
Kasimier
11-04-2009 9:23 AM |
Yes you are right (had to write about it at first) the names of the fields really are not loaded if CurrentItem will be empty, I'll try to find a solution and write it here. If you find before, write here :)