gr672_bda 4 years ago
parent
commit
0394e79188

+ 53 - 0
ModelView/DelegateCommand.cs

@@ -0,0 +1,53 @@
+#region (c) 2019 Gilles Macabies All right reserved
+
+//   Author     : Gilles Macabies
+//   Solution   : DataGridFilter
+//   Projet     : DataGridFilter
+//   File       : DelegateCommand.cs
+//   Created    : 05/11/2019
+
+#endregion
+
+using System;
+using System.Windows.Input;
+
+namespace DemoApplication.ModelView
+{
+    /// <summary>
+    ///     DelegateCommand borrowed from
+    ///     http://www.wpftutorial.net/DelegateCommand.html
+    /// </summary>
+    public class DelegateCommand : ICommand
+    {
+        private readonly Predicate<object> _canExecute;
+        private readonly Action<object> _execute;
+
+        public DelegateCommand(Action<object> execute,
+            Predicate<object> canExecute = null)
+        {
+            _execute = execute;
+            _canExecute = canExecute;
+        }
+
+        public void RaiseCanExecuteChanged()
+        {
+            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
+        }
+
+        #region ICommand Members
+
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return _canExecute == null || _canExecute(parameter);
+        }
+
+        public void Execute(object parameter)
+        {
+            _execute(parameter);
+        }
+
+        #endregion
+    }
+}

+ 134 - 0
ModelView/ModelView.cs

@@ -0,0 +1,134 @@
+#region (c) 2019 Gilles Macabies All right reserved
+
+//   Author     : Gilles Macabies
+//   Solution   : DataGridFilter
+//   Projet     : DataGridFilter
+//   File       : ModelView.cs
+//   Created    : 31/10/2019
+
+#endregion (c) 2019 Gilles Macabies All right reserved
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Data;
+using System.Windows.Input;
+
+// ReSharper disable MemberCanBePrivate.Global
+
+namespace DemoApplication.ModelView
+{
+    public class ModelView : INotifyPropertyChanged
+    {
+        #region Public Constructors
+
+        public ModelView()
+        {
+            FillData();
+        }
+
+        #endregion Public Constructors
+
+        #region Command
+
+        /// <summary>
+        ///     Refresh all
+        /// </summary>
+        public ICommand RefreshCommand => new DelegateCommand(RefreshData);
+
+        #endregion Command
+
+        #region Private Fields
+
+        private ICollectionView collView;
+
+        private string search;
+
+        #endregion Private Fields
+
+        #region Public Properties
+
+        public ObservableCollection<Employe> Employes { get; set; }
+        public ObservableCollection<Employe> FilteredList { get; set; }
+
+        /// <summary>
+        /// Global filter
+        /// </summary>
+        public string Search
+        {
+            get => search;
+            set
+            {
+                search = value;
+
+                collView.Filter = e =>
+                {
+                    var item = (Employe)e;
+                    return item != null && ((item.LastName?.StartsWith(search, StringComparison.OrdinalIgnoreCase) ?? false)
+                                            || (item.FirstName?.StartsWith(search, StringComparison.OrdinalIgnoreCase) ?? false));
+                };
+
+                collView.Refresh();
+
+                FilteredList = new ObservableCollection<Employe>(collView.OfType<Employe>().ToList());
+
+                OnPropertyChanged("Search");
+                OnPropertyChanged("FilteredList");
+            }
+        }
+
+        #endregion Public Properties
+
+        #region Public Events
+
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        #endregion Public Events
+
+        #region Private Methods
+
+        /// <summary>
+        /// Fill data
+        /// </summary>
+        private void FillData()
+        {
+            search = "";
+
+            var employe = new List<Employe>();
+
+            // number of elements to be generated
+            const int @int = 100000;
+
+            // for distinct lastname set "true" at CreateRandomEmployee(true)
+            for (var i = 0; i < @int; i++)
+                employe.Add(RandomGenerator.CreateRandomEmployee(true));
+
+            Employes = new ObservableCollection<Employe>(employe.AsParallel().OrderBy(o => o.LastName));
+
+            FilteredList = new ObservableCollection<Employe>(Employes);
+            collView = CollectionViewSource.GetDefaultView(FilteredList);
+
+            OnPropertyChanged("Search");
+            OnPropertyChanged("Employes");
+            OnPropertyChanged("FilteredList");
+        }
+
+        private void OnPropertyChanged(string propertyname)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
+        }
+
+        /// <summary>
+        /// refresh data
+        /// </summary>
+        /// <param name="obj"></param>
+        private void RefreshData(object obj)
+        {
+            FillData();
+        }
+
+        #endregion Private Methods
+    }
+}

+ 121 - 0
ModelView/RandomGenerator.cs

@@ -0,0 +1,121 @@
+using System;
+using System.Diagnostics;
+
+// ReSharper disable CheckNamespace
+
+namespace DemoApplication.ModelView
+{
+    public static class RandomGenerator
+    {
+        #region Private Fields
+
+        private static readonly string[] Consonants =
+        {
+            "b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"
+        };
+
+        private static readonly string[] FirstNames =
+        {
+            "Aiden","Jackson","Mason","Liam","Jacob","Jayden","Ethan","Noah","Lucas","Logan","Caleb","Caden","Jack","Ryan","Connor","Michael","Elijah","Brayden","Benjamin","Nicholas","Alexander",
+            "William","Matthew","James","Landon","Nathan","Dylan","Evan","Luke","Andrew","Gabriel","Gavin","Joshua","Owen","Daniel","Carter","Tyler","Cameron","Christian","Wyatt","Henry","Eli",
+            "Joseph","Max","Isaac","Samuel","Anthony","Grayson","Zachary","David","Christopher","John","Isaiah","Levi","Jonathan","Oliver","Chase","Cooper","Tristan","Colton","Austin","Colin",
+            "Charlie","Dominic","Parker","Hunter","Thomas","Alex","Ian","Jordan","Cole","Julian","Aaron","Carson","Miles","Blake","Brody","Adam","Sebastian","Adrian","Nolan","Sean","Riley",
+            "Bentley","Xavier","Hayden","Jeremiah","Jason","Jake","Asher","Micah","Jace","Brandon","Josiah","Hudson","Nathaniel","Bryson","Ryder","Justin","Bryce", "",  null
+        };
+
+        private static readonly string[] LastNames =
+                {
+            "Smith", "Johnson", "Williams", "Jones", "Brown", "Davis", "Miller", "Wilson", "Moore", "Taylor", "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin", "Thompson", "Garcia",
+            "Martinez", "Robinson", "Clark", "Rodriguez", "Lewis", "Lee", "Walker", "Hall", "Allen", "Young", "Hernandez", "King", "Wright", "Lopez", "Hill", "Scott", "Green", "Adams", "Baker",
+            "Gonzalez", "Nelson", "Carter", "Mitchell", "Perez", "Roberts", "Turner", "Phillips", "Campbell", "Parker", "Evans", "Edwards", "Collins", "Stewart", "Sanchez", "Morris", "Rogers",
+            "Reed", "Cook", "Morgan", "Bell", "Murphy", "Bailey", "Rivera", "Cooper", "Richardson", "Cox", "Howard", "Ward", "Torres", "Peterson", "Gray", "Ramirez", "James", "Watson", "Brooks",
+            "Kelly", "Sanders", "Price", "Bennett", "Wood", "Barnes", "Ross", "Henderson", "Coleman", "Jenkins", "Perry", "Powell", "Long", "Patterson", "Hughes", "Flores", "Washington", "Butler",
+            "Simmons", "Foster", "Gonzales", "Bryant", "Alexander", "Russell", "Griffin", "Diaz", "Hayes", "", null
+        };
+
+        private static readonly Random Rnd;
+        private static readonly string[] Vowels = { "a", "e", "i", "o", "u", "y" };
+
+        #endregion Private Fields
+
+        #region Public Constructors
+
+        static RandomGenerator()
+        {
+            Rnd = new Random();
+        }
+
+        #endregion Public Constructors
+
+        #region Public Methods
+
+        /// <summary>
+        /// Create random employee
+        /// </summary>
+        /// <returns></returns>
+        public static Employe CreateRandomEmployee(bool distinct = false)
+        {
+            // distinct lastName or not
+            var emp = new Employe
+                (distinct ? GenerateName() : LastNames[Rnd.Next(LastNames.Length)],
+                FirstNames[Rnd.Next(FirstNames.Length)],
+                // salary
+                Rnd.Next(1, 11) * 10,
+                // start date
+                Rnd.Next(0, 10) != 1 ? new DateTime(2015 + Rnd.Next(4), Rnd.Next(12) + 1, Rnd.Next(28) + 1) : (DateTime?)null,
+                // is manager
+                Rnd.Next() % 2 == 1);
+            return emp;
+        }
+
+        /// <summary>
+        /// Display a list of random names (for testing)
+        /// </summary>
+        /// <param name="num"></param>
+        public static void Generate(int num = 100)
+        {
+            for (var i = 0; i < num; i++)
+            {
+                GenerateName(true);
+            }
+        }
+
+        #endregion Public Methods
+
+        #region Private Methods
+
+        /// <summary>
+        /// GenerateName
+        /// </summary>
+        /// <returns></returns>
+        private static string GenerateName(bool debug = false)
+        {
+            var name = "";
+
+            // Capitalize the first letter 
+            name += Consonants[Rnd.Next(Consonants.Length)].ToUpper();
+            name += Vowels[Rnd.Next(Vowels.Length)];
+
+            var nameLength = name.Length;
+
+            // set the final name size
+            var len = Rnd.Next(5, 8 + nameLength);
+
+            while (nameLength <= len)
+            {
+                if (nameLength % 2 == 1)
+                    name += Consonants[Rnd.Next(Consonants.Length)];
+                else
+                    name += Vowels[Rnd.Next(Vowels.Length)];
+
+                nameLength++;
+            }
+
+            Debug.WriteLineIf(debug, $"{name,-16} length : {name.Length}");
+
+            return name;
+        }
+
+        #endregion Private Methods
+    }
+}

+ 9 - 6
ProjectAnalogParus/AccrualsPage.xaml

@@ -20,20 +20,23 @@
         <control:FilterDataGrid CanUserAddRows="False" IsReadOnly="True" ItemsSource="{Binding FilteredList, UpdateSourceTrigger=PropertyChanged}" x:Name="FilterDataGrid" FilterLanguage="Russian" HorizontalAlignment="Left" AutoGenerateColumns="False" Height="188" Margin="10,74,0,0" VerticalAlignment="Top" Width="780" >
 
             <control:FilterDataGrid.Columns>
-                <control:DataGridTextColumn Binding="{Binding Student.LastName}" Header="Фамилия" Width="3*" IsColumnFiltered="True" />
-                <control:DataGridTextColumn Binding="{Binding Student.FirstName}" Header="Имя" Width="2*" IsColumnFiltered="True" >
+                <control:DataGridTextColumn Binding="{Binding Student.LastName}" Header="Фамилия" Width="3*"/>
+                <control:DataGridTextColumn Binding="{Binding Student.FirstName}" Header="Имя" Width="2*">
 
                 </control:DataGridTextColumn>
-                <control:DataGridTextColumn Binding="{Binding Student.Middlename}" Header="Отчество" Width="3*" IsColumnFiltered="True" />
-                <control:DataGridTextColumn Binding="{Binding User.FullNameUser}" Header="Ответсвенное лицо" Width="4*" IsColumnFiltered="True"  />
+                <control:DataGridTextColumn Binding="{Binding Student.Middlename}" Header="Отчество" Width="3*"  />
+                <control:DataGridTextColumn Binding="{Binding User.FullNameUser}" Header="Ответсвенное лицо" Width="4*"   />
                 <control:DataGridTextColumn Binding="{Binding DateAccruals,StringFormat='yyyy-MM-dd'}" Header="Дата начисления" Width="4*" IsColumnFiltered="True"  />
-                <control:DataGridTextColumn Binding="{Binding Scholarship.NameScholarship}" Header="Стипендия" Width="3*" IsColumnFiltered="True"  />
-                <control:DataGridTextColumn Binding="{Binding Encouragement.NameTypeEncouragement}" Header="Поощрение" Width="3*" IsColumnFiltered="True"  />
+                <control:DataGridTextColumn Binding="{Binding Scholarship.NameScholarship}" Header="Стипендия" Width="3*"   />
+                <control:DataGridTextColumn Binding="{Binding Encouragement.NameTypeEncouragement}" Header="Поощрение" Width="3*"  />
                 <control:DataGridTextColumn Binding="{Binding Amount}" Header="Сумма" Width="2*" IsColumnFiltered="True"  />
             </control:FilterDataGrid.Columns>
 
         </control:FilterDataGrid>
 
+      
+
+
 
         <Button Content="Экспорт Excel" HorizontalAlignment="Left" Margin="51,285,0,0" VerticalAlignment="Top" Width="97" Click="ExcelClick"/>
         <TextBox x:Name="TxtSearch" TextChanged="TxtSearch_TextChanged" HorizontalAlignment="Left" Height="24" Margin="105,31,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="170"/>

+ 17 - 3
ProjectAnalogParus/AccrualsPage.xaml.cs

@@ -1,4 +1,5 @@
-using Microsoft.Build.Tasks.Deployment.Bootstrapper;
+using DemoApplication.ModelView;
+using Microsoft.Build.Tasks.Deployment.Bootstrapper;
 using Microsoft.Office.Interop.Excel;
 using System;
 using System.Collections.Generic;
@@ -31,11 +32,24 @@ namespace ProjectAnalogParus
         public AccrualsPage()
         {
             InitializeComponent();
-                          
+
+            AppDomain.CurrentDomain.FirstChanceException += (source, e) =>
+            {
+                Debug.WriteLine("FirstChanceException event raised in {0}: {1}",
+                    AppDomain.CurrentDomain.FriendlyName, e.Exception.Message);
+            };
+
+            DataContext = new ModelClass();
 
         }
+        
+        private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
+        {
+            var index = e.Row.GetIndex() + 1;
+            e.Row.Header = $"{index}";
+        }
+
 
-           
         private void ExcelClick(object sender, RoutedEventArgs e)
         {          
             Excel.Application excel = new Excel.Application();

+ 53 - 0
ProjectAnalogParus/DelegateCommand.cs

@@ -0,0 +1,53 @@
+#region (c) 2019 Gilles Macabies All right reserved
+
+//   Author     : Gilles Macabies
+//   Solution   : DataGridFilter
+//   Projet     : DataGridFilter
+//   File       : DelegateCommand.cs
+//   Created    : 05/11/2019
+
+#endregion
+
+using System;
+using System.Windows.Input;
+
+namespace DemoApplication.ModelView
+{
+    /// <summary>
+    ///     DelegateCommand borrowed from
+    ///     http://www.wpftutorial.net/DelegateCommand.html
+    /// </summary>
+    public class DelegateCommand : ICommand
+    {
+        private readonly Predicate<object> _canExecute;
+        private readonly Action<object> _execute;
+
+        public DelegateCommand(Action<object> execute,
+            Predicate<object> canExecute = null)
+        {
+            _execute = execute;
+            _canExecute = canExecute;
+        }
+
+        public void RaiseCanExecuteChanged()
+        {
+            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
+        }
+
+        #region ICommand Members
+
+        public event EventHandler CanExecuteChanged;
+
+        public bool CanExecute(object parameter)
+        {
+            return _canExecute == null || _canExecute(parameter);
+        }
+
+        public void Execute(object parameter)
+        {
+            _execute(parameter);
+        }
+
+        #endregion
+    }
+}

+ 122 - 0
ProjectAnalogParus/ModelClass.cs

@@ -0,0 +1,122 @@
+using DemoApplication.ModelView;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using System.Windows.Input;
+
+namespace ProjectAnalogParus
+{
+    public class ModelClass : INotifyPropertyChanged
+    {
+        #region Public Constructors
+
+        public ModelClass()
+        {
+            FillData();
+        }
+
+        #endregion Public Constructors
+
+        #region Command
+
+        /// <summary>
+        ///     Refresh all
+        /// </summary>
+        public ICommand RefreshCommand => new DelegateCommand(RefreshData);
+
+        #endregion Command
+
+        #region Private Fields
+
+        private ICollectionView collView;
+
+        private string search;
+
+        #endregion Private Fields
+
+        #region Public Properties
+
+        public ObservableCollection<Student> Employes { get; set; }
+        public ObservableCollection<Student> FilteredList { get; set; }
+
+        /// <summary>
+        /// Global filter
+        /// </summary>
+        public string Search
+        {
+            get => search;
+            set
+            {
+                search = value;
+
+                collView.Filter = e =>
+                {
+                    var item = (Student)e;
+                    return item != null && ((item.LastName?.StartsWith(search, StringComparison.OrdinalIgnoreCase) ?? false)
+                                            || (item.FirstName?.StartsWith(search, StringComparison.OrdinalIgnoreCase) ?? false));
+                };
+
+                collView.Refresh();
+
+                FilteredList = new ObservableCollection<Student>(collView.OfType<Student>().ToList());
+
+                OnPropertyChanged("Search");
+                OnPropertyChanged("FilteredList");
+            }
+        }
+
+        #endregion Public Properties
+
+        #region Public Events
+
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        #endregion Public Events
+
+        #region Private Methods
+
+        /// <summary>
+        /// Fill data
+        /// </summary>
+        private void FillData()
+        {
+
+            search = "";
+
+            var employe = new List<Student>();      
+
+            
+            
+
+            Employes = new ObservableCollection<Student>(employe.AsParallel().OrderBy(o => o.LastName));
+
+            FilteredList = new ObservableCollection<Student>(Employes);
+            collView = CollectionViewSource.GetDefaultView(FilteredList);
+
+            OnPropertyChanged("Search");
+            OnPropertyChanged("Employes");
+            OnPropertyChanged("FilteredList");
+        }
+
+        private void OnPropertyChanged(string propertyname)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
+        }
+
+        /// <summary>
+        /// refresh data
+        /// </summary>
+        /// <param name="obj"></param>
+        private void RefreshData(object obj)
+        {
+            FillData();
+        }
+
+        #endregion Private Methods
+    }
+}

+ 2 - 0
ProjectAnalogParus/ProjectAnalogParus.csproj

@@ -130,6 +130,7 @@
     <Compile Include="CompositionExperience.cs">
       <DependentUpon>Model.tt</DependentUpon>
     </Compile>
+    <Compile Include="DelegateCommand.cs" />
     <Compile Include="DeleteEncouragementWindow.xaml.cs">
       <DependentUpon>DeleteEncouragementWindow.xaml</DependentUpon>
     </Compile>
@@ -201,6 +202,7 @@
       <DesignTime>True</DesignTime>
       <DependentUpon>Model.tt</DependentUpon>
     </Compile>
+    <Compile Include="ModelClass.cs" />
     <Compile Include="Parametrs.cs">
       <DependentUpon>Model.tt</DependentUpon>
     </Compile>