This question is locked. New answers and comments are not allowed.
Hello,
i have a project where we have this kind of object :
- ListingProduct (DisplayName, List<property>) which properties is a Property {string name, string value}.
And i need to offer to my users the choice of shown column (who correspond to properties) by a context menu on header fields.
Here the code :
When i sort by context menu, all works fine.
But i want to use the same hability by clicking on header.
So,
i tried to manage that in Sorting Event, but when i set the new Sorting State, it seem to be lost, have you an idea ?
I don't want to use the custom DataTable you provided (http://blogs.telerik.com/blogs/posts/09-04-23/lightweight_datatable_for_your_silverlight_applications.aspx and http://blogs.telerik.com/blogs/Libraries/Vladimir_Enchev/SilverlightDataTable_Q3_2009_SP2.sflb?download=true is broken),
because i need to have the possibility to loadrowdetails without loading and have context menu action on each element (like modify and other), and if i haven't the id column, i cannot retrieve the value.
Thank you.
i have a project where we have this kind of object :
- ListingProduct (DisplayName, List<property>) which properties is a Property {string name, string value}.
And i need to offer to my users the choice of shown column (who correspond to properties) by a context menu on header fields.
Here the code :
| using System; |
| using System.Net; |
| using System.Windows; |
| using System.Windows.Controls; |
| using System.Windows.Documents; |
| using System.Windows.Ink; |
| using System.Windows.Input; |
| using System.Windows.Media; |
| using System.Windows.Media.Animation; |
| using System.Windows.Shapes; |
| using System.ComponentModel; |
| using Telerik.Windows.Controls; |
| using Telerik.Windows.Controls.GridView; |
| using Telerik.Windows; |
| using System.Windows.Data; |
| using System.Collections.Generic; |
| using System.Linq; |
| using CatalogManager.WCFCatalogManager; |
| using System.Collections.ObjectModel; |
| using Telerik.Windows.Data; |
| using System.Collections; |
| using System.Diagnostics; |
| namespace CatalogManager.Views.CatalogV.Renderer |
| { |
| public class HeaderColumnChooser |
| { |
| private RadGridView grid = null; |
| public HeaderColumnChooser(RadGridView grid) |
| { |
| this.grid = grid; |
| } |
| public static readonly DependencyProperty IsEnabledProperty |
| = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(HeaderColumnChooser), |
| new System.Windows.PropertyMetadata(new PropertyChangedCallback(OnIsEnabledPropertyChanged))); |
| public static void SetIsEnabled(DependencyObject dependencyObject, bool enabled) |
| { |
| dependencyObject.SetValue(IsEnabledProperty, enabled); |
| } |
| public static bool GetIsEnabled(DependencyObject dependencyObject) |
| { |
| return (bool)dependencyObject.GetValue(IsEnabledProperty); |
| } |
| private static void OnIsEnabledPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) |
| { |
| RadGridView grid = dependencyObject as RadGridView; |
| if (grid != null) |
| { |
| if ((bool)e.NewValue) |
| { |
| // Create new GridViewHeaderMenu and attach RowLoaded event. |
| HeaderColumnChooser menu = new HeaderColumnChooser(grid); |
| menu.Attach(); |
| } |
| } |
| } |
| private void Attach() |
| { |
| if (grid != null) |
| { |
| this.grid.Loaded += new RoutedEventHandler(grid_Loaded); |
| this.grid.DataLoaded += new EventHandler<EventArgs>(grid_DataLoaded); |
| this.grid.Sorting += new EventHandler<GridViewSortingEventArgs>(grid_Sorting); |
| this.grid.Sorted += new EventHandler<GridViewSortedEventArgs>(grid_Sorted); |
| this.grid.SortDescriptors.Clear(); |
| } |
| } |
| void grid_Sorted(object sender, GridViewSortedEventArgs e) |
| { |
| e.Handled = true; |
| } |
| private SortingState st { get; set; } |
| private string ns { get; set; } |
| void grid_Sorting(object sender, GridViewSortingEventArgs e) |
| { |
| string action = ""; |
| if (e.NewSortingState == SortingState.Ascending) |
| action = "SortAsc"; |
| else if (e.NewSortingState == SortingState.Descending) |
| action = "SortDesc"; |
| else |
| action = "ClearSort"; |
| SortGrid(e.Column, action); |
| ns = e.Column.UniqueName; |
| if (e.OldSortingState == SortingState.None) |
| { |
| e.NewSortingState = SortingState.Ascending; |
| } |
| else if (e.OldSortingState == SortingState.Ascending) |
| { |
| e.NewSortingState = SortingState.Descending; |
| } |
| else |
| { |
| e.NewSortingState = SortingState.None; |
| } |
| e.Column.SortingState = e.NewSortingState; |
| e.Cancel = true; |
| } |
| void grid_DataLoaded(object sender, EventArgs e) |
| { |
| GridViewHeaderRow headerRow = grid.ChildrenOfType<GridViewHeaderRow>().FirstOrDefault(); |
| if (headerRow != null) |
| { |
| InitializeMenus(headerRow); |
| } |
| } |
| void grid_Loaded(object sender, RoutedEventArgs e) |
| { |
| } |
| private void InitializeMenus(GridViewHeaderRow row) |
| { |
| IEnumerable<GridViewHeaderCell> cells = row.Cells.OfType<GridViewHeaderCell>(); |
| foreach (GridViewHeaderCell cell in cells) |
| { |
| // create menu |
| RadContextMenu contextMenu = new RadContextMenu(); |
| // set menu Theme |
| StyleManager.SetTheme(contextMenu, StyleManager.GetTheme(grid)); |
| RadMenuItem item = new RadMenuItem() { Name = "SortAsc", Header = String.Format(@"Trier par ordre croissant par ""{0}""", cell.Column.Header) }; |
| contextMenu.Items.Add(item); |
| item = new RadMenuItem() { Name = "SortDesc", Header = String.Format(@"Trier par ordre décroissant par ""{0}""", cell.Column.Header) }; |
| contextMenu.Items.Add(item); |
| item = new RadMenuItem() { Name = "ClearSort", Header = String.Format(@"Effacer le tri de ""{0}""", cell.Column.Header) }; |
| contextMenu.Items.Add(item); |
| item = new RadMenuItem() { Name = "ChooseColumns", Header = "Choisir les colonnes" }; |
| contextMenu.Items.Add(item); |
| contextMenu.AddHandler(RadMenuItem.ClickEvent, new RoutedEventHandler(OnMenuItemClick)); |
| // attach menu |
| RadContextMenu.SetContextMenu(cell, contextMenu); |
| } |
| } |
| void OnMenuItemClick(object sender, RoutedEventArgs e) |
| { |
| RadContextMenu menu = (RadContextMenu)sender; |
| RadMenuItem clickedItem = ((RadRoutedEventArgs)e).OriginalSource as RadMenuItem; |
| GridViewColumn column = ((GridViewHeaderCell)menu.UIElement).Column; |
| if (clickedItem.Parent is RadMenuItem) |
| return; |
| string header = Convert.ToString(clickedItem.Name); |
| if (header == "ChooseColumns") |
| { |
| ObservableCollection<InfoPropSchema> props; |
| props = (grid.ParentOfType<CatalogProducts>()).propsSchema; |
| ChooseProperties chooseProperties = new ChooseProperties(props); |
| chooseProperties.Closing += new EventHandler<CancelEventArgs>(chooseProperties_Closing); |
| chooseProperties.Show(); |
| return; |
| } |
| SortGrid(column, header); |
| } |
| void SortGrid(GridViewColumn column, string action) |
| { |
| if (grid.Columns.Count > 4) |
| Debug.WriteLine(System.DateTime.Now.ToString() + " " + grid.Columns[4].SortingState + " - SortGridStart"); |
| using (grid.DeferRefresh()) |
| { |
| InfoPropSchema ips = (grid.ParentOfType<CatalogProducts>()).propsSchema.First(o => o.Name == column.UniqueName); |
| SortedCollection<ListingCatalogItem> soc = new SortedCollection<ListingCatalogItem>(new sortInfoProp(ips)); |
| ObservableCollection<ListingCatalogItem> list; |
| if ((grid.ParentOfType<CatalogProducts>()).MyDefinitionType == DefinitionType.ProductDefinition) |
| { |
| list = ((grid.ParentOfType<CatalogProducts>()).MyCollection); |
| } |
| else |
| { |
| list = ((grid.ParentOfType<CatalogProducts>()).MyCollectionSousCategories); |
| } |
| switch (action) |
| { |
| case "SortAsc": |
| list.ToList().ForEach(o => soc.Add(o)); |
| list.Clear(); |
| soc.ToList().ForEach(o => list.Add(o)); |
| (grid.ItemsSource as QueryableCollectionView).Refresh(); |
| soc.Clear(); |
| soc = null; |
| break; |
| case "SortDesc": |
| list.ToList().ForEach(o => soc.Add(o)); |
| list.Clear(); |
| soc.Reverse().ToList().ForEach(o => list.Add(o)); |
| (grid.ItemsSource as QueryableCollectionView).Refresh(); |
| soc.Clear(); |
| soc = null; |
| break; |
| case "ClearSort": |
| break; |
| } |
| } |
| } |
| void chooseProperties_Closing(object sender, CancelEventArgs e) |
| { |
| Reload(true); |
| } |
| public void Reload(bool rebind) |
| { |
| GridViewColumnCollection gvcc = new GridViewColumnCollection(); |
| grid.SortDescriptors.Clear(); |
| grid.Columns.Clear(); |
| grid.Columns.Add(new GridViewToggleRowDetailsColumn() |
| { |
| Header = "QuickEdit" |
| }); |
| (grid.ParentOfType<CatalogProducts>()).propsSchema.Where(o => o.IsShown).ToList().ForEach( |
| delegate(InfoPropSchema a) |
| { |
| if (!gvcc.Any<GridViewColumn>(o => o != null && o.UniqueName == a.Name)) |
| { |
| Binding myBind = new Binding("ListProperties") |
| { |
| Converter = new ListPropriete(a), |
| ConverterParameter = a.Name |
| }; |
| gvcc.Add( |
| new GridViewDataColumn() |
| { |
| Header = a.DisplayName, |
| DataMemberBinding = myBind, |
| UniqueName = a.Name, |
| IsReorderable = false, |
| IsFilterable = false, |
| IsSortable=true, |
| SortMemberPath = a.Name, |
| DataType = typeof(String) |
| } |
| ); |
| } |
| }); |
| gvcc.ToList<GridViewColumn>().ForEach(o => grid.Columns.Add(o)); |
| if (rebind) |
| grid.Rebind(); |
| } |
| } |
| public class sortInfoProp : IComparer<ListingCatalogItem> |
| { |
| private InfoPropSchema _propertyNameToSort; |
| public sortInfoProp(InfoPropSchema propertyNameToSort) |
| { |
| _propertyNameToSort = propertyNameToSort; |
| } |
| #region IComparer<ListingCatalogItem> Members |
| public int Compare(ListingCatalogItem x, ListingCatalogItem y) |
| { |
| ListingInfoProp FromCompare = x.ListProperties.FirstOrDefault(o => o.Name == _propertyNameToSort.Name); |
| ListingInfoProp ToCompare = y.ListProperties.FirstOrDefault(o => o.Name == _propertyNameToSort.Name); |
| if (FromCompare != null && ToCompare == null) |
| return 1; |
| else if (FromCompare == null && ToCompare != null) |
| return -1; |
| else if (FromCompare == null && ToCompare == null || FromCompare.Value == ToCompare.Value) |
| return 0; |
| switch (_propertyNameToSort.ItemDataType) |
| { |
| case ItemDataType.BigInteger: |
| return long.Parse(FromCompare.Value).CompareTo(long.Parse(ToCompare.Value)); |
| case ItemDataType.Boolean: |
| return Boolean.Parse(FromCompare.Value).CompareTo(Boolean.Parse(ToCompare.Value)); |
| case ItemDataType.Currency: |
| return Decimal.Parse(FromCompare.Value).CompareTo(Decimal.Parse(ToCompare.Value)); |
| case ItemDataType.DateTime: |
| return DateTime.Parse(FromCompare.Value).CompareTo(DateTime.Parse(ToCompare.Value)); |
| case ItemDataType.Double: |
| return Double.Parse(FromCompare.Value).CompareTo(Double.Parse(ToCompare.Value)); |
| case ItemDataType.Float: |
| return float.Parse(FromCompare.Value).CompareTo(float.Parse(ToCompare.Value)); |
| case ItemDataType.Integer: |
| return int.Parse(FromCompare.Value).CompareTo(int.Parse(ToCompare.Value)); |
| default: |
| return FromCompare.Value.CompareTo(ToCompare.Value); |
| } |
| } |
| #endregion |
| } |
| public static class InfoPropExtensions |
| { |
| public static object GetTypedValue(this ListingInfoProp b, InfoPropSchema schemaProperty) |
| { |
| if (b == null) |
| return ""; |
| switch (schemaProperty.ItemDataType) |
| { |
| case ItemDataType.Boolean: |
| return String.IsNullOrEmpty(b.Value) ? false : Boolean.Parse(b.Value); |
| case ItemDataType.String: |
| return b.Value; |
| default: |
| return b.Value; |
| } |
| } |
| } |
| internal class ListPropriete : IValueConverter |
| { |
| private InfoPropSchema schemaProperty { get; set; } |
| public ListPropriete(InfoPropSchema _schemaProperty) |
| { |
| schemaProperty = _schemaProperty; |
| } |
| #region IValueConverter Members |
| public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
| { |
| if (value is ObservableCollection<ListingInfoProp> && parameter != null && parameter is string) |
| { |
| string tmp = (string)parameter; |
| return (value as ObservableCollection<ListingInfoProp>).FirstOrDefault(o => o.Name == tmp).GetTypedValue(schemaProperty); |
| } |
| else |
| { |
| return value; |
| } |
| } |
| public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
| { |
| return ""; |
| } |
| #endregion |
| } |
| } |
When i sort by context menu, all works fine.
But i want to use the same hability by clicking on header.
So,
i tried to manage that in Sorting Event, but when i set the new Sorting State, it seem to be lost, have you an idea ?
I don't want to use the custom DataTable you provided (http://blogs.telerik.com/blogs/posts/09-04-23/lightweight_datatable_for_your_silverlight_applications.aspx and http://blogs.telerik.com/blogs/Libraries/Vladimir_Enchev/SilverlightDataTable_Q3_2009_SP2.sflb?download=true is broken),
because i need to have the possibility to loadrowdetails without loading and have context menu action on each element (like modify and other), and if i haven't the id column, i cannot retrieve the value.
Thank you.
