Welcome to the Xceed Community | Help
Community Search  
More Search Options

Datagrid selection at start

Sort Posts: Previous Next
  •  10-03-2011, 9:11 AM Post no. 31131

    Datagrid selection at start

    Hello!

    In my company, we are using Xceed Datagrid. I have a problem, for which I didn't find any solution in the forum.

    So, the datagrid works, but I want to pre-select rows when the grid is displayed. Because I am using it as a selector, and when the grid is closed and opened again, the same rows should be selected. Of course this does happen, if the same instance is displayed, but what about the case, when the whole application is restarted?

    I am binding Items to the collection of all items, and this works properly. I am also binding SelectedItems to another collection, which receives the selected items. But it does not work in the other direction, and although Binding.Mode is set to TwoWay, it does not help.

    As the SelectedItem obviously does not work in the collection ---> datagrid direction, I tried to manually select rows at the beginning, but it also does not work, as "Items" is empty at the beginning, as the actual binding seems to be performed later, not immediately after the instantiation of the XAML View object. Also, I don't find any event, which would signal me, when the binding was completed.

    What can I do? The source code is too complex to post it here.

     

    Thanks,

    Sergej

  •  10-03-2011, 3:06 PM Post no. 31137 in reply to 31131

    Re: Datagrid selection at start

    Hi Sergej,

    Are you able to attach the project to the forum post? Or you can send your sample application to support@xceed.com  and we will be able to see exactly what you are trying to do and provide you with a possible answer. Can you please make a reference to this post so that I know it is you who is emailing us?


    Marc

    Developer in Technical Support
    Xceed - Multi-talented components - http://xceed.com
  •  10-04-2011, 7:02 AM Post no. 31144 in reply to 31137

    Re: Datagrid selection at start

    The project is huge, with thousands of files and probably a million lines of code. But I hope I have successfully extracted the relevant portion of code here.

    All the important points in the source code are marked with "!!!". After the constructor of AssetSelectorPM is called, its "SelectedAssets" property is filled in the other code.

    Anyway, what do you suggest to select rows at the startup? As "SelectedItems" cannot be bound in XAML, but must be in the C# code. Should this work already if bound in the code?

    Thanks,

    Sergej

     

    ==============================

    AssetDto.cs:
    ==============================

        [Serializable]
        public class AssetDto: GroupedDtoBase {
            private Guid _id;
            public Guid ID {
                get {return _id;}
                set {_id = value; RaisePropertyChanged(() => ID);}
            }

            private int _assetID;
            public int AssetID {
                get {return _assetID;}
                set {_assetID = value; RaisePropertyChanged(() => AssetID);}
            }

            private string _registrationNumber;
            public string RegistrationNumber {
                get {return _registrationNumber;}
                set {_registrationNumber = value; RaisePropertyChanged(() => RegistrationNumber);}
            }

            // other properties here...
        }
        


    ==============================

    IAssetSelectorPM.cs:
    ==============================

        public interface IAssetsSelectorPM {
            GenericViewCollection<AssetDto> Assets {get;}
            GenericViewCollection<AssetDto> SelectedAssets {get; set;}
            IAssetsSelectorView View {get;}
        }



    ==============================

    IAssetSelectorView.cs:
    ==============================

        public interface IAssetsSelectorView {
            IAssetsSelectorPM Model {set;}
        }
        


    ==============================

    AssetSelectorView.xaml:
    ==============================
        
        
        <UserControl.Resources>
            <xcdg:DataGridCollectionViewSource x:Key="Assets"
                                                   Source="{Binding Assets}"
                                                   AutoFilterMode="None" AutoCreateItemProperties="true" >
            </xcdg:DataGridCollectionViewSource>
        </UserControl.Resources>
        <DockPanel>
            <xcdg:DataGridControl Name="UI_AssetsGrid" Grid.Row="0" AutoCreateColumns="True"
                                      ItemScrollingBehavior="Immediate" ReadOnly="True"  
                                      ItemsSource="{Binding Source={StaticResource Assets}}"
                                      SelectionMode="Extended" NavigationBehavior="RowOnly"
                                      Margin="5,5,0,2">
            </xcdg:DataGridControl>
        </DockPanel>
        
        

    ==============================

    AssetSelectorView.xaml.cs:
    ==============================
        
        public partial class AssetsSelectorView: UserControl, IAssetsSelectorView {
            public AssetsSelectorView() {
                InitializeComponent();
            }

            public IAssetsSelectorPM Model {
                set {
                    DataContext = value;
                    // !!! set bindings that can not be set in xaml
                    new CollectionBinder(UI_AssetsGrid.SelectedItems, Model.SelectedAssets, BindingMode.TwoWay);
                }
                get {
                    return DataContext as IAssetsSelectorPM;
                }
            }
        }
        
        
        
    ==============================

    AssetSelectorPM.cs:
    ==============================    

        public class AssetsSelectorPM: BasePM, IAssetsSelectorPM {
            private readonly IAssetService _assetService;
            private readonly IGroupDefinitionsStorage _groupDefinitionsStorage;

            public IAssetsSelectorView View {get; private set;}

            public AssetsSelectorPM(IAssetsSelectorView view, IAssetService assetService, IGroupDefinitionsStorage groupDefinitionsStorage, IUIFacade uiFacade, IAssetFilterPM assetFilterPM) {
                _assetService = assetService;
                _groupDefinitionsStorage = groupDefinitionsStorage;
                _uiFacade = uiFacade;
                FilterPM = assetFilterPM;
                FilterPM.UpdateResultsCommand = new DelegateCommand<object>(x => PopulateAssets());

                PopulateAssets();

                View = view;
                View.Model = this;
                
                // !!! here, the "Assets" is already filled, but the "Items" in Datagrid is not bound, so I cannot manually select the Items here.
            }


            private GenericViewCollection<AssetDto> _assets;
            private GenericViewCollection<AssetDto> _selectedAssets = new GenericViewCollection<AssetDto>();
            private readonly IUIFacade _uiFacade;

            public GenericViewCollection<AssetDto> Assets {
                get {return _assets;}
                private set {
                    _assets = value;
                    RaisePropertyChanged(() => Assets);
                }
            }

            public GenericViewCollection<AssetDto> SelectedAssets {
                get {return _selectedAssets;}

                set {_selectedAssets = value;}
            }

            private void PopulateAssets() {
                var pds = new List<PropertyDescriptor> {
                    new NamedPropertyDescriptor<AssetDto>(x => x.InternalNumber, Resources.InternalNumber),
                    new NamedPropertyDescriptor<AssetDto>(x => x.RegistrationNumber, Resources.LicensePlate)                                                                            
                };

                try {
                    GroupDefinitionsDescriptorProvider<Asset>.AppendPropertyDescriptorsForGroupDefinitions(
                        _groupDefinitionsStorage.GroupDefinitionsForName(Asset.AssetGroupingName), pds);

                    var assets = _assetService.GetAssetDtosForLoggedUser(FilterPM.Filter);
                    Assets = new GenericViewCollection<AssetDto>(assets, pds);
                }
                catch (Exception ee) {
                    _uiFacade.ShowErrorMessage(ee.Message, ee);
                }
            }
        }
        

    ==============================

    CollectionBinder.cs:
    ==============================    

        
        public class CollectionBinder {
            private IList _sourceCollection;
            private IList _targetCollection;
            private Func<object, object> _sourceToTargetConversion;
            private Func<object, object> _targetToSourceConversion;
            private bool _skipNullValues;

            public CollectionBinder(IList sourceCollection, IList targetCollection, BindingMode bindingMode) {
                ArgumentHelper.AssertNotNull(sourceCollection, "sourceCollection");
                ArgumentHelper.AssertNotNull(targetCollection, "targetCollection");
                ArgumentHelper.AssertEnumMember<BindingMode>(bindingMode, "bindingMode", BindingMode.OneTime, BindingMode.OneWay, BindingMode.OneWayToSource, BindingMode.TwoWay);

                _sourceToTargetConversion = x => x;
                _targetToSourceConversion = x => x;
                _skipNullValues = false;

                if (bindingMode == BindingMode.OneWayToSource) {
                    _targetCollection = sourceCollection;
                    _sourceCollection = targetCollection;
                    bindingMode = BindingMode.OneWay;
                }
                else {
                    _sourceCollection = sourceCollection;
                    _targetCollection = targetCollection;
                }

                InitialSync(sourceCollection, targetCollection);            
                var notifiableSource = _sourceCollection as INotifyCollectionChanged;
                var notifiableTarget = _targetCollection as INotifyCollectionChanged;
                if ((bindingMode == BindingMode.OneWay || bindingMode == BindingMode.TwoWay) && notifiableSource != null) {
                    notifiableSource.CollectionChanged += CollectionBinder_SourceCollectionChanged;
                }

                if (bindingMode == BindingMode.TwoWay && notifiableTarget != null)
                    notifiableTarget.CollectionChanged += CollectionBinder_TargetCollectionChanged;
            }

            public CollectionBinder(IList sourceCollection, IList targetCollection, BindingMode bindingMode, Func<object, object> sourceToTargetConversion, Func<object, object> targetToSourceConversion)
                : this(sourceCollection, targetCollection, bindingMode) {
                _sourceToTargetConversion = sourceToTargetConversion;
                _targetToSourceConversion = targetToSourceConversion;
            }

            public CollectionBinder(IList sourceCollection, IList targetCollection, BindingMode bindingMode, Func<object, object> sourceToTargetConversion, Func<object, object> targetToSourceConversion, bool skipNullValues)
                : this(sourceCollection, targetCollection, bindingMode) {
                _sourceToTargetConversion = sourceToTargetConversion;
                _targetToSourceConversion = targetToSourceConversion;
                _skipNullValues = true;
            }

            public CollectionBinder(IList sourceCollection, IList targetCollection, BindingMode bindingMode, Func<object, object> sourceToTargetConversion)
                : this(sourceCollection, targetCollection, bindingMode) {
                _sourceToTargetConversion = sourceToTargetConversion;
            }

            private void InitialSync(IList sourceCollection, IList targetCollection) {
                targetCollection.Clear();
                foreach (object item in sourceCollection) {
                    var converted = _sourceToTargetConversion(item);
                    if (converted == null && _skipNullValues) continue;
                    targetCollection.Add(_sourceToTargetConversion(item));
                }
            }

            private bool _sourceChangedFirst = false;
            private void CollectionBinder_SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
                if (_targetChangedFirst) return;
                _sourceChangedFirst = true;
                SynchroniseCollection(_targetCollection, e, _sourceToTargetConversion);
                _sourceChangedFirst = false;
            }

            private bool _targetChangedFirst = false;
            private void CollectionBinder_TargetCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
                if (_sourceChangedFirst) return;
                _targetChangedFirst = true;
                SynchroniseCollection(_sourceCollection, e, _targetToSourceConversion);
                _targetChangedFirst = false;
            }

            private void SynchroniseCollection(IList collectionToSync, NotifyCollectionChangedEventArgs e, Func<object, object> converter) {
                if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Replace) {
                    foreach (object item in e.NewItems) {
                        var converted = converter(item);
                        if (converted == null && _skipNullValues) continue;
                        collectionToSync.Add(converted);
                    }
                }
                else if (e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace) {
                    foreach (object item in e.OldItems) {
                        var converted = converter(item);
                        if (converted == null && _skipNullValues)
                            continue;
                        collectionToSync.Remove(converted);
                    }
                }
                else if (e.Action == NotifyCollectionChangedAction.Reset) {
                    if (collectionToSync == _targetCollection)
                        InitialSync(_sourceCollection, _targetCollection);
                    else
                        InitialSync(_targetCollection, _sourceCollection);
                }
            }
        }

View as RSS news feed in XML
Contact | Site Map | Reviews | Legal Terms of Use | Trademarks | Privacy Statement Copyright 2011 Xceed Software Inc.