├── .gitattributes
├── .github
└── workflows
│ └── vale.yml
├── .gitignore
├── CS
├── MVVMExpenses.sln
└── MVVMExpenses
│ ├── App.config
│ ├── Common
│ ├── AppIcon.ico
│ ├── CommonResources.Designer.cs
│ ├── CommonResources.resx
│ ├── DataModel
│ │ ├── DbExceptions.cs
│ │ ├── EntityFramework
│ │ │ ├── DbConnectionFactory.cs
│ │ │ ├── DbExceptionsConverter.cs
│ │ │ ├── DbReadOnlyRepository.cs
│ │ │ ├── DbRepository.cs
│ │ │ ├── DbUnitOfWork.cs
│ │ │ ├── DbUnitOfWorkFactory.cs
│ │ │ └── InstantFeedbackSource.cs
│ │ ├── EntityState.cs
│ │ ├── IReadOnlyRepository.cs
│ │ ├── IRepository.cs
│ │ ├── IUnitOfWork.cs
│ │ └── UnitOfWorkBase.cs
│ ├── Utils
│ │ ├── DbExtensions.cs
│ │ └── ExpressionHelper.cs
│ └── ViewModel
│ │ ├── CollectionViewModel.cs
│ │ ├── DocumentsViewModel.cs
│ │ ├── EntitiesViewModel.cs
│ │ ├── ISingleObjectViewModel.cs
│ │ ├── InstantFeedbackCollectionViewModel.cs
│ │ ├── LayoutSettings.Designer.cs
│ │ ├── LayoutSettings.settings
│ │ ├── LookUpEntitiesViewModel.cs
│ │ ├── Messages.cs
│ │ ├── PeekCollectionViewModel.cs
│ │ ├── ReadOnlyCollectionViewModel.cs
│ │ ├── SingleObjectViewModel.cs
│ │ └── ViewModelLogicalLayoutHelper.cs
│ ├── Data
│ └── Expenses.sqlite3
│ ├── DataBase
│ ├── DataDirectoryHelper.cs
│ └── DbContext.cs
│ ├── MVVMExpenses.csproj
│ ├── Models
│ ├── Account.cs
│ ├── Category.cs
│ ├── CredentialsSource.cs
│ ├── MyDbContextDataModel
│ │ ├── IMyDbContextUnitOfWork.cs
│ │ ├── MyDbContextUnitOfWork.cs
│ │ └── UnitOfWorkSource.cs
│ ├── Transaction.cs
│ └── User.cs
│ ├── Program.cs
│ ├── Properties
│ ├── AssemblyInfo.cs
│ ├── DataSources
│ │ ├── MVVMExpenses.DataModels.Account.datasource
│ │ ├── MVVMExpenses.DataModels.Category.datasource
│ │ ├── MVVMExpenses.DataModels.Transaction.datasource
│ │ └── MVVMExpenses.Models.SampleUserList.datasource
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
│ ├── ViewModels
│ ├── Account
│ │ ├── AccountCollectionViewModel.cs
│ │ └── AccountViewModel.cs
│ ├── Category
│ │ ├── CategoryCollectionViewModel.cs
│ │ └── CategoryViewModel.cs
│ ├── LoginViewModel.cs
│ ├── MyDbContextViewModel.cs
│ ├── MyDbContextViewModel.partial.cs
│ └── Transaction
│ │ ├── TransactionCollectionViewModel.cs
│ │ └── TransactionViewModel.cs
│ ├── Views
│ ├── Account
│ │ ├── AccountsEditFormView.Designer.cs
│ │ ├── AccountsEditFormView.cs
│ │ ├── AccountsEditFormView.resx
│ │ ├── AccountsView.Designer.cs
│ │ ├── AccountsView.cs
│ │ └── AccountsView.resx
│ ├── Category
│ │ ├── CategoriesEditFormView.Designer.cs
│ │ ├── CategoriesEditFormView.cs
│ │ ├── CategoriesEditFormView.resx
│ │ ├── CategoriesView.Designer.cs
│ │ ├── CategoriesView.cs
│ │ └── CategoriesView.resx
│ ├── LoginView.Designer.cs
│ ├── LoginView.cs
│ ├── LoginView.resx
│ ├── MainView.Designer.cs
│ ├── MainView.cs
│ ├── MainView.resx
│ └── Transaction
│ │ ├── TransactionsEditFormView.Designer.cs
│ │ ├── TransactionsEditFormView.cs
│ │ ├── TransactionsEditFormView.resx
│ │ ├── TransactionsView.Designer.cs
│ │ ├── TransactionsView.cs
│ │ └── TransactionsView.resx
│ ├── packages.config
│ └── sqlite
│ ├── System.Data.SQLite.EF6.dll
│ └── System.Data.SQLite.dll
├── LICENSE
├── Readme.md
├── VB
├── MVVMExpenses.sln
└── MVVMExpenses
│ ├── AppIcon.ico
│ ├── Common
│ ├── AppIcon.ico
│ ├── CommonResources.Designer.vb
│ ├── CommonResources.resx
│ ├── DataModel
│ │ ├── DbExceptions.vb
│ │ ├── EntityFramework
│ │ │ ├── DbExceptionsConverter.vb
│ │ │ ├── DbReadOnlyRepository.vb
│ │ │ ├── DbRepository.vb
│ │ │ ├── DbUnitOfWork.vb
│ │ │ ├── DbUnitOfWorkFactory.vb
│ │ │ └── InstantFeedbackSource.vb
│ │ ├── EntityState.vb
│ │ ├── IReadOnlyRepository.vb
│ │ ├── IRepository.vb
│ │ ├── IUnitOfWork.vb
│ │ └── UnitOfWorkBase.vb
│ ├── Utils
│ │ ├── DbExtensions.vb
│ │ └── ExpressionHelper.vb
│ └── ViewModel
│ │ ├── CollectionViewModel.vb
│ │ ├── DocumentsViewModel.vb
│ │ ├── EntitiesViewModel.vb
│ │ ├── ISingleObjectViewModel.vb
│ │ ├── InstantFeedbackCollectionViewModel.vb
│ │ ├── LayoutSettings.Designer.vb
│ │ ├── LayoutSettings.settings
│ │ ├── LookUpEntitiesViewModel.vb
│ │ ├── Messages.vb
│ │ ├── PeekCollectionViewModel.vb
│ │ ├── ReadOnlyCollectionViewModel.vb
│ │ ├── SingleObjectViewModel.vb
│ │ └── ViewModelLogicalLayoutHelper.vb
│ ├── Data
│ └── Expenses.sqlite3
│ ├── DataBase
│ ├── DataDirectoryHelper.vb
│ ├── DbContext.vb
│ └── MyDbSQLiteConfiguration.vb
│ ├── MVVMExpenses.vbproj
│ ├── Models
│ ├── Account.vb
│ ├── Category.vb
│ ├── CredentialsSource.vb
│ ├── MyDbContextDataModel
│ │ ├── IMyDbContextUnitOfWork.vb
│ │ ├── MyDbContextUnitOfWork.vb
│ │ └── UnitOfWorkSource.vb
│ ├── Transaction.vb
│ └── User.vb
│ ├── My Project
│ ├── AssemblyInfo.vb
│ ├── DataSources
│ │ ├── MVVMExpenses.DataModels.Account.datasource
│ │ ├── MVVMExpenses.DataModels.Category.datasource
│ │ └── MVVMExpenses.DataModels.Transaction.datasource
│ ├── Resources.Designer.vb
│ ├── Resources.resx
│ ├── Settings.Designer.vb
│ └── Settings.settings
│ ├── Program.vb
│ ├── ViewModels
│ ├── Account
│ │ ├── AccountCollectionViewModel.vb
│ │ └── AccountViewModel.vb
│ ├── Category
│ │ ├── CategoryCollectionViewModel.vb
│ │ └── CategoryViewModel.vb
│ ├── LoginViewModel.vb
│ ├── MyDbContextViewModel.partial.vb
│ ├── MyDbContextViewModel.vb
│ └── Transaction
│ │ ├── TransactionCollectionViewModel.vb
│ │ └── TransactionViewModel.vb
│ ├── Views
│ ├── Account
│ │ ├── AccountsEditFormView.Designer.vb
│ │ ├── AccountsEditFormView.resx
│ │ ├── AccountsEditFormView.vb
│ │ ├── AccountsView.Designer.vb
│ │ ├── AccountsView.resx
│ │ └── AccountsView.vb
│ ├── Category
│ │ ├── CategoriesEditFormView.Designer.vb
│ │ ├── CategoriesEditFormView.resx
│ │ ├── CategoriesEditFormView.vb
│ │ ├── CategoriesView.Designer.vb
│ │ ├── CategoriesView.resx
│ │ └── CategoriesView.vb
│ ├── LoginView.Designer.vb
│ ├── LoginView.resx
│ ├── LoginView.vb
│ ├── MainView.Designer.vb
│ ├── MainView.resx
│ ├── MainView.vb
│ └── Transaction
│ │ ├── TransactionsEditFormView.Designer.vb
│ │ ├── TransactionsEditFormView.resx
│ │ ├── TransactionsEditFormView.vb
│ │ ├── TransactionsView.Designer.vb
│ │ ├── TransactionsView.resx
│ │ └── TransactionsView.vb
│ ├── app.config
│ ├── packages.config
│ └── sqlite
│ ├── System.Data.SQLite.EF6.dll
│ └── System.Data.SQLite.dll
└── config.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | VB/* linguist-vendored
2 | scripts linguist-vendored
3 | *.css linguist-detectable=false
4 | *.aff linguist-detectable=false
--------------------------------------------------------------------------------
/.github/workflows/vale.yml:
--------------------------------------------------------------------------------
1 | name: vale-validation
2 | on:
3 | pull_request:
4 | paths:
5 | - README.md
6 | - readme.md
7 | - Readme.md
8 |
9 | jobs:
10 | vale:
11 | name: runner / vale
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: clone repo
15 | uses: actions/checkout@v4
16 | - name: clone vale-styles repo
17 | uses: actions/checkout@v4
18 | with:
19 | repository: DevExpress/vale-styles
20 | path: vale-styles
21 | ssh-key: ${{ secrets.VALE_STYLES_ACCESS_KEY }}
22 | - name: copy vale rules to the root repo
23 | run: shopt -s dotglob && cp -r ./vale-styles/vale/* .
24 | - name: vale linter check
25 | uses: DevExpress/vale-action@reviewdog
26 | with:
27 | files: '["README.md", "readme.md", "Readme.md"]'
28 | fail_on_error: true
29 | filter_mode: nofilter
30 | reporter: github-check
31 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 14
3 | VisualStudioVersion = 14.0.23107.0
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MVVMExpenses", "MVVMExpenses\MVVMExpenses.csproj", "{E7AE86FF-3BDC-43E1-A33A-63A6970D3670}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Any CPU = Debug|Any CPU
10 | Debug|x86 = Debug|x86
11 | Release|Any CPU = Release|Any CPU
12 | Release|x86 = Release|x86
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Debug|Any CPU.ActiveCfg = Debug|x86
16 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Debug|Any CPU.Build.0 = Debug|x86
17 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Debug|x86.ActiveCfg = Debug|x86
18 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Debug|x86.Build.0 = Debug|x86
19 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Release|Any CPU.Build.0 = Release|Any CPU
21 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Release|x86.ActiveCfg = Release|x86
22 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Release|x86.Build.0 = Release|x86
23 | EndGlobalSection
24 | GlobalSection(SolutionProperties) = preSolution
25 | HideSolutionNode = FALSE
26 | EndGlobalSection
27 | EndGlobal
28 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/AppIcon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevExpress-Examples/winforms-mvvm-expenses-app/70a139e6d5909c97e63090201977325d1be58b9a/CS/MVVMExpenses/Common/AppIcon.ico
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/DbExceptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace MVVMExpenses.Common.DataModel {
5 | ///
6 | /// The database-independent exception used in Data Layer and View Model Layer to handle database errors.
7 | ///
8 | public class DbException : Exception {
9 |
10 | ///
11 | /// Initializes a new instance of the DbRepository class.
12 | ///
13 | /// An error message text.
14 | /// An error message caption text.
15 | /// An underlying exception.
16 | public DbException(string errorMessage, string errorCaption, Exception innerException)
17 | : base(innerException.Message, innerException) {
18 | ErrorMessage = errorMessage;
19 | ErrorCaption = errorCaption;
20 | }
21 |
22 | /// The error message text.
23 | public string ErrorMessage { get; private set; }
24 |
25 | /// The error message caption text.
26 | public string ErrorCaption { get; private set; }
27 | }
28 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/EntityFramework/DbConnectionFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.Common;
4 | using System.Data.SQLite;
5 | using System.Data.SQLite.EF6;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | //using DevExpress.DocumentServices.ServiceModel.DataContracts.Xpf.Designer;
11 | using DevExpress.Internal;
12 |
13 | namespace MVVMExpenses.Common.DataModel.EntityFramework {
14 | public class SQLiteConnectionFactory : System.Data.Entity.Infrastructure.IDbConnectionFactory {
15 | static string filePath;
16 | public DbConnection CreateConnection(string nameOrConnectionString) {
17 | if(filePath == null) {
18 | filePath = DataDirectoryHelper.GetFile("expenses.sqlite3", DataDirectoryHelper.DataFolderName);
19 | File.SetAttributes(filePath, File.GetAttributes(filePath) & ~FileAttributes.ReadOnly);
20 | }
21 | return new SQLiteConnection(new SQLiteConnectionStringBuilder { DataSource = filePath }.ConnectionString);
22 | }
23 | }
24 | public class MyDbSQLiteConfiguration : System.Data.Entity.DbConfiguration {
25 | public MyDbSQLiteConfiguration() {
26 | SetDefaultConnectionFactory(new SQLiteConnectionFactory());
27 | SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
28 | SetProviderFactory("System.Data.SQLite.EF6", System.Data.SQLite.EF6.SQLiteProviderFactory.Instance);
29 | Type t = Type.GetType("System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6", true, true);
30 | System.Reflection.FieldInfo fi = t.GetField("Instance", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
31 | SetProviderServices("System.Data.SQLite", (System.Data.Entity.Core.Common.DbProviderServices)fi.GetValue(null));
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/EntityFramework/DbExceptionsConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data.Entity.Infrastructure;
3 | using System.Data.Entity.Validation;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace MVVMExpenses.Common.DataModel.EntityFramework {
8 | ///
9 | /// Provides methods to convert Entity Framework exceptions to database-independent exceptions used in Data Layer and View Model Layer.
10 | ///
11 | public static class DbExceptionsConverter {
12 |
13 | ///
14 | /// Converts System.Data.Entity.Infrastructure.DbUpdateException exception to database-independent DbException exception used in Data Layer and View Model Layer.
15 | ///
16 | /// Exception to convert.
17 | public static DbException Convert(DbUpdateException exception) {
18 | Exception originalException = exception;
19 | while(originalException.InnerException != null) {
20 | originalException = originalException.InnerException;
21 | }
22 | return new DbException(originalException.Message, CommonResources.Exception_UpdateErrorCaption, exception);
23 | }
24 |
25 | ///
26 | /// Converts System.Data.Entity.Validation.DbEntityValidationException exception to database-independent DbException exception used in Data Layer and View Model Layer.
27 | ///
28 | /// Exception to convert.
29 | public static DbException Convert(DbEntityValidationException exception) {
30 | StringBuilder stringBuilder = new StringBuilder();
31 | foreach(DbEntityValidationResult validationResult in exception.EntityValidationErrors) {
32 | foreach(DbValidationError error in validationResult.ValidationErrors) {
33 | if(stringBuilder.Length > 0)
34 | stringBuilder.AppendLine();
35 | stringBuilder.Append(error.PropertyName + ": " + error.ErrorMessage);
36 | }
37 | }
38 | return new DbException(stringBuilder.ToString(), CommonResources.Exception_ValidationErrorCaption, exception);
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/EntityFramework/DbReadOnlyRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using System.Data.Entity;
5 | using System.Collections.Generic;
6 | using System.Collections.ObjectModel;
7 |
8 | namespace MVVMExpenses.Common.DataModel.EntityFramework {
9 | ///
10 | /// A DbReadOnlyRepository is a IReadOnlyRepository interface implementation representing the collection of all entities in the unit of work, or that can be queried from the database, of a given type.
11 | /// DbReadOnlyRepository objects are created from a DbUnitOfWork using the GetReadOnlyRepository method.
12 | /// DbReadOnlyRepository provides only read-only operations against entities of a given type.
13 | ///
14 | /// Repository entity type.
15 | /// DbContext type.
16 | public class DbReadOnlyRepository : DbRepositoryQuery, IReadOnlyRepository
17 | where TEntity : class
18 | where TDbContext : DbContext {
19 |
20 | readonly Func> dbSetAccessor;
21 | readonly DbUnitOfWork unitOfWork;
22 |
23 | ///
24 | /// Initializes a new instance of DbReadOnlyRepository class.
25 | ///
26 | /// Owner unit of work that provides context for repository entities.
27 | /// Function that returns DbSet entities from Entity Framework DbContext.
28 | public DbReadOnlyRepository(DbUnitOfWork unitOfWork, Func> dbSetAccessor)
29 | : base(() => dbSetAccessor(unitOfWork.Context)) {
30 | this.dbSetAccessor = dbSetAccessor;
31 | this.unitOfWork = unitOfWork;
32 | }
33 |
34 | protected DbSet DbSet {
35 | get { return dbSetAccessor(unitOfWork.Context); }
36 | }
37 |
38 | protected TDbContext Context {
39 | get { return unitOfWork.Context; }
40 | }
41 |
42 | #region IReadOnlyRepository
43 | IUnitOfWork IReadOnlyRepository.UnitOfWork {
44 | get { return unitOfWork; }
45 | }
46 | #endregion
47 | }
48 |
49 | ///
50 | /// DbRepositoryQuery is an IRepositoryQuery interface implementation that is an extension of IQueryable designed to specify the related objects to include in query results.
51 | ///
52 | /// An entity type.
53 | public class DbRepositoryQuery : RepositoryQueryBase, IRepositoryQuery where TEntity : class {
54 |
55 | ///
56 | /// Initializes a new instance of the DesignTimeRepositoryQuery class.
57 | ///
58 | /// A function that returns an IQueryable instance which is used by DbRepositoryQuery to perform queries.
59 | public DbRepositoryQuery(Func> getQueryable)
60 | : base(getQueryable) { }
61 |
62 | IRepositoryQuery IRepositoryQuery.Include(Expression> path) {
63 | return new DbRepositoryQuery(() => Queryable.Include(path));
64 | }
65 |
66 | IRepositoryQuery IRepositoryQuery.Where(Expression> predicate) {
67 | return new DbRepositoryQuery(() => Queryable.Where(predicate));
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/EntityFramework/DbUnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.Entity;
4 | using System.Data.Entity.Validation;
5 | using System.Data.Entity.Infrastructure;
6 | using System.Linq;
7 | using System.Linq.Expressions;
8 |
9 | namespace MVVMExpenses.Common.DataModel.EntityFramework {
10 | ///
11 | /// A DbUnitOfWork instance represents the implementation of the Unit Of Work pattern
12 | /// such that it can be used to query from a database and group together changes that will then be written back to the store as a unit.
13 | ///
14 | /// DbContext type.
15 | public abstract class DbUnitOfWork : UnitOfWorkBase, IUnitOfWork where TContext : DbContext {
16 |
17 | readonly Lazy context;
18 |
19 | public DbUnitOfWork(Func contextFactory) {
20 | context = new Lazy(contextFactory);
21 | }
22 |
23 | ///
24 | /// Instance of underlying DbContext.
25 | ///
26 | public TContext Context { get { return context.Value; } }
27 |
28 | void IUnitOfWork.SaveChanges() {
29 | try {
30 | Context.SaveChanges();
31 | }
32 | catch(DbEntityValidationException ex) {
33 | throw DbExceptionsConverter.Convert(ex);
34 | }
35 | catch(DbUpdateException ex) {
36 | throw DbExceptionsConverter.Convert(ex);
37 | }
38 | }
39 |
40 | bool IUnitOfWork.HasChanges() {
41 | return Context.ChangeTracker.HasChanges();
42 | }
43 |
44 | protected IRepository
45 | GetRepository(Func> dbSetAccessor, Expression> getPrimaryKeyExpression)
46 | where TEntity : class {
47 | return GetRepositoryCore, TEntity>(() => new DbRepository(this, dbSetAccessor, getPrimaryKeyExpression));
48 | }
49 |
50 | protected IReadOnlyRepository
51 | GetReadOnlyRepository(Func> dbSetAccessor)
52 | where TEntity : class {
53 | return GetRepositoryCore, TEntity>(() => new DbReadOnlyRepository(this, dbSetAccessor));
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/EntityFramework/DbUnitOfWorkFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Data;
4 | using System.Data.Entity;
5 | using System.Linq.Expressions;
6 | using System.Collections.Generic;
7 | using MVVMExpenses.Common.Utils;
8 | using MVVMExpenses.Common.DataModel;
9 | using DevExpress.Mvvm;
10 | using System.Collections;
11 | using System.ComponentModel;
12 | using DevExpress.Data.Linq;
13 | using DevExpress.Data.Linq.Helpers;
14 | using DevExpress.Data.Async.Helpers;
15 |
16 | namespace MVVMExpenses.Common.DataModel.EntityFramework {
17 | class DbUnitOfWorkFactory : IUnitOfWorkFactory where TUnitOfWork : IUnitOfWork {
18 | Func createUnitOfWork;
19 |
20 | public DbUnitOfWorkFactory(Func createUnitOfWork) {
21 | this.createUnitOfWork = createUnitOfWork;
22 | }
23 |
24 | TUnitOfWork IUnitOfWorkFactory.CreateUnitOfWork() {
25 | return createUnitOfWork();
26 | }
27 |
28 | IInstantFeedbackSource IUnitOfWorkFactory.CreateInstantFeedbackSource(
29 | Func> getRepositoryFunc,
30 | Func, IQueryable> projection) {
31 | var threadSafeProperties = new TypeInfoProxied(TypeDescriptor.GetProperties(typeof(TProjection)), null).UIDescriptors;
32 | if(projection == null) {
33 | projection = x => x as IQueryable;
34 | }
35 | var source = new EntityInstantFeedbackSource((GetQueryableEventArgs e) => e.QueryableSource = projection(getRepositoryFunc(createUnitOfWork()))) {
36 | KeyExpression = getRepositoryFunc(createUnitOfWork()).GetPrimaryKeyPropertyName(),
37 | };
38 | return new InstantFeedbackSource(source, threadSafeProperties);
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/EntityFramework/InstantFeedbackSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Data;
4 | using System.Data.Entity;
5 | using System.Linq.Expressions;
6 | using System.Collections.Generic;
7 | using MVVMExpenses.Common.Utils;
8 | using MVVMExpenses.Common.DataModel;
9 | using DevExpress.Mvvm;
10 | using System.Collections;
11 | using System.ComponentModel;
12 | using DevExpress.Data.Linq;
13 | using DevExpress.Data.Linq.Helpers;
14 | using DevExpress.Data.Async.Helpers;
15 |
16 | namespace MVVMExpenses.Common.DataModel.EntityFramework {
17 |
18 | class InstantFeedbackSource : IInstantFeedbackSource
19 | where TEntity : class {
20 | readonly EntityInstantFeedbackSource source;
21 | readonly PropertyDescriptorCollection threadSafeProperties;
22 |
23 | public InstantFeedbackSource(EntityInstantFeedbackSource source, PropertyDescriptorCollection threadSafeProperties) {
24 | this.source = source;
25 | this.threadSafeProperties = threadSafeProperties;
26 | }
27 |
28 | bool IListSource.ContainsListCollection { get { return ((IListSource)source).ContainsListCollection; } }
29 |
30 | IList IListSource.GetList() {
31 | return ((IListSource)source).GetList();
32 | }
33 |
34 | TProperty IInstantFeedbackSource.GetPropertyValue(object threadSafeProxy, Expression> propertyExpression) {
35 | var propertyName = ExpressionHelper.GetPropertyName(propertyExpression);
36 | var threadSafeProperty = threadSafeProperties[propertyName];
37 | return (TProperty)threadSafeProperty.GetValue(threadSafeProxy);
38 | }
39 |
40 | bool IInstantFeedbackSource.IsLoadedProxy(object threadSafeProxy) {
41 | return threadSafeProxy is ReadonlyThreadSafeProxyForObjectFromAnotherThread;
42 | }
43 |
44 | void IInstantFeedbackSource.Refresh() {
45 | source.Refresh();
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/EntityState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace MVVMExpenses.Common.DataModel {
5 | ///
6 | /// Represents the state of the entity relative to the unit of work.
7 | ///
8 | public enum EntityState {
9 |
10 | ///
11 | /// The object exists but is not being tracked.
12 | /// An entity is in this state immediately after it has been created and before it is added to the unit of work.
13 | /// An entity is also in this state after it has been removed from the unit of work by calling the IUnitOfWork.Detach method.
14 | ///
15 | Detached = 1,
16 |
17 | ///
18 | /// The object has not been modified since it was attached to the unit of work or since the last time that the IUnitOfWork.SaveChanges method was called.
19 | ///
20 | Unchanged = 2,
21 |
22 | ///
23 | /// The object is new, has been added to the unit of work, and the IUnitOfWork.SaveChanges method has not been called.
24 | /// After the changes are saved, the object state changes to Unchanged.
25 | ///
26 | Added = 4,
27 |
28 | ///
29 | /// The object has been deleted from the unit of work. After the changes are saved, the object state changes to Detached.
30 | ///
31 | Deleted = 8,
32 |
33 | ///
34 | /// One of the scalar properties on the object has been modified and the IUnitOfWork.SaveChanges method has not been called.
35 | /// After the changes are saved, the object state changes to Unchanged.
36 | ///
37 | Modified = 16,
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/IUnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Linq;
4 | using System.Linq.Expressions;
5 |
6 | namespace MVVMExpenses.Common.DataModel {
7 | ///
8 | /// The IUnitOfWork interface represents the Unit Of Work pattern
9 | /// such that it can be used to query from a database and group together changes that will then be written back to the store as a unit.
10 | ///
11 | public interface IUnitOfWork {
12 | ///
13 | /// Saves all changes made in this unit of work to the underlying store.
14 | ///
15 | void SaveChanges();
16 |
17 | ///
18 | /// Checks if the unit of work is tracking any new, deleted, or changed entities or relationships that will be sent to the store if SaveChanges() is called.
19 | ///
20 | bool HasChanges();
21 | }
22 |
23 | ///
24 | /// Provides the method to create a unit of work of a given type.
25 | ///
26 | /// A unit of work type.
27 | public interface IUnitOfWorkFactory where TUnitOfWork : IUnitOfWork {
28 |
29 | ///
30 | /// Creates a new unit of work.
31 | ///
32 | TUnitOfWork CreateUnitOfWork();
33 | IInstantFeedbackSource CreateInstantFeedbackSource(Func> getRepositoryFunc, Func, IQueryable> projection)
34 | where TEntity : class, new()
35 | where TProjection : class;
36 | }
37 |
38 | public interface IInstantFeedbackSource : IListSource
39 | where TEntity : class {
40 | void Refresh();
41 | TProperty GetPropertyValue(object threadSafeProxy, Expression> propertyExpression);
42 | bool IsLoadedProxy(object threadSafeProxy);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/DataModel/UnitOfWorkBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Collections.Generic;
4 | using System.Linq.Expressions;
5 |
6 | namespace MVVMExpenses.Common.DataModel {
7 | ///
8 | /// The base class for unit of works that provides the storage for repositories.
9 | ///
10 | public class UnitOfWorkBase {
11 |
12 | readonly Dictionary repositories = new Dictionary();
13 |
14 | protected TRepository GetRepositoryCore(Func createRepositoryFunc)
15 | where TRepository : IReadOnlyRepository
16 | where TEntity : class {
17 | object result = null;
18 | if(!repositories.TryGetValue(typeof(TEntity), out result)) {
19 | result = createRepositoryFunc();
20 | repositories[typeof(TEntity)] = result;
21 | }
22 | return (TRepository)result;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/Utils/DbExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Linq;
4 |
5 | namespace MVVMExpenses.Common.Utils {
6 | ///
7 | /// Provides the extension method for implementations of the IQueryable interface.
8 | ///
9 | public static class DbExtensions {
10 |
11 | ///
12 | /// Forces entities to be loaded locally from the IQueryable instance.
13 | ///
14 | /// An instance of the IQueryable interface from which to load entities.
15 | public static void Load(this IQueryable source) {
16 | IEnumerator enumerator = source.GetEnumerator();
17 | while(enumerator.MoveNext()) {
18 | }
19 | }
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/ViewModel/ISingleObjectViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations;
3 | using System.Linq;
4 | using System.Linq.Expressions;
5 | using DevExpress.Mvvm;
6 | using DevExpress.Mvvm.POCO;
7 | using DevExpress.Mvvm.DataAnnotations;
8 | using MVVMExpenses.Common.Utils;
9 | using MVVMExpenses.Common.DataModel;
10 |
11 | namespace MVVMExpenses.Common.ViewModel {
12 | ///
13 | /// The base interface for view models representing a single entity.
14 | ///
15 | /// An entity type.
16 | /// An entity primary key type.
17 | public interface ISingleObjectViewModel {
18 |
19 | ///
20 | /// The entity represented by a view model.
21 | ///
22 | TEntity Entity { get; }
23 |
24 | ///
25 | /// The entity primary key value.
26 | ///
27 | TPrimaryKey PrimaryKey { get; }
28 | }
29 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/ViewModel/LayoutSettings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18052
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace MVVMExpenses.Common.ViewModel {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
16 | internal sealed partial class LayoutSettings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static LayoutSettings defaultInstance = ((LayoutSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new LayoutSettings())));
19 |
20 | public static LayoutSettings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("")]
29 | public string LogicalLayout {
30 | get {
31 | return ((string)(this["LogicalLayout"]));
32 | }
33 | set {
34 | this["LogicalLayout"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("")]
41 | public string ViewsLayout {
42 | get {
43 | return ((string)(this["ViewsLayout"]));
44 | }
45 | set {
46 | this["ViewsLayout"] = value;
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/ViewModel/LayoutSettings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/ViewModel/LookUpEntitiesViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.ComponentModel;
4 | using DevExpress.Mvvm;
5 | using DevExpress.Mvvm.POCO;
6 | using System.Collections.ObjectModel;
7 | using MVVMExpenses.Common.Utils;
8 | using MVVMExpenses.Common.DataModel;
9 |
10 | namespace MVVMExpenses.Common.ViewModel {
11 | ///
12 | /// Represents a POCO view models used by SingleObjectViewModel to exposing collections of related entities.
13 | /// This is a partial class that provides an extension point to add custom properties, commands and override methods without modifying the auto-generated code.
14 | ///
15 | /// A repository entity type.
16 | /// A projection entity type.
17 | /// A primary key value type.
18 | /// A unit of work type.
19 | public class LookUpEntitiesViewModel : EntitiesViewModel, IDocumentContent
20 | where TEntity : class
21 | where TProjection : class
22 | where TUnitOfWork : IUnitOfWork {
23 |
24 | ///
25 | /// Creates a new instance of LookUpEntitiesViewModel as a POCO view model.
26 | ///
27 | /// A factory used to create a unit of work instance.
28 | /// A function that returns a repository representing entities of the given type.
29 | /// An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type.
30 | public static LookUpEntitiesViewModel Create(
31 | IUnitOfWorkFactory unitOfWorkFactory,
32 | Func> getRepositoryFunc,
33 | Func, IQueryable> projection = null) {
34 | return ViewModelSource.Create(() => new LookUpEntitiesViewModel(unitOfWorkFactory, getRepositoryFunc, projection));
35 | }
36 |
37 | ///
38 | /// Initializes a new instance of the LookUpEntitiesViewModel class.
39 | /// This constructor is declared protected to avoid an undesired instantiation of the LookUpEntitiesViewModel type without the POCO proxy factory.
40 | ///
41 | /// A factory used to create a unit of work instance.
42 | /// A function that returns a repository representing entities of the given type.
43 | /// A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type.
44 | protected LookUpEntitiesViewModel(
45 | IUnitOfWorkFactory unitOfWorkFactory,
46 | Func> getRepositoryFunc,
47 | Func, IQueryable> projection
48 | ) : base(unitOfWorkFactory, getRepositoryFunc, projection) {
49 | }
50 |
51 | protected override IEntitiesChangeTracker CreateEntitiesChangeTracker() {
52 | return new EntitiesChangeTracker(this);
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/ViewModel/Messages.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.ComponentModel;
4 |
5 | namespace MVVMExpenses.Common.ViewModel {
6 | ///
7 | /// Represents the type of an entity state change notification that is shown when the IUnitOfWork.SaveChanges method has been called.
8 | ///
9 | public enum EntityMessageType {
10 |
11 | ///
12 | /// A new entity has been added to the unit of work.
13 | ///
14 | Added,
15 |
16 | ///
17 | /// An entity has been removed from the unit of work.
18 | ///
19 | Deleted,
20 |
21 | ///
22 | /// One of the entity properties has been modified.
23 | ///
24 | Changed
25 | }
26 |
27 | ///
28 | /// Provides the information about an entity state change notification that is shown when an entity has been added, removed or modified, and the IUnitOfWork.SaveChanges method has been called.
29 | ///
30 | /// An entity type.
31 | /// A primary key value type.
32 | public class EntityMessage {
33 |
34 | ///
35 | /// Initializes a new instance of the EntityMessage class.
36 | ///
37 | /// A primary key of an entity that has been added, removed or modified.
38 | /// An entity state change notification type.
39 | public EntityMessage(TPrimaryKey primaryKey, EntityMessageType messageType) {
40 | this.PrimaryKey = primaryKey;
41 | this.MessageType = messageType;
42 | }
43 |
44 | ///
45 | /// The primary key of entity that has been added, deleted or modified.
46 | ///
47 | public TPrimaryKey PrimaryKey { get; private set; }
48 |
49 | ///
50 | /// The entity state change notification type.
51 | ///
52 | public EntityMessageType MessageType { get; private set; }
53 | }
54 |
55 | ///
56 | /// A message notifying that all view models should save changes. Usually sent by DocumentsViewModel when the SaveAll command is executed.
57 | ///
58 | public class SaveAllMessage {
59 | }
60 |
61 | ///
62 | /// A message notifying that all view models should close itself. Usually sent by DocumentsViewModel when the CloseAll command is executed.
63 | ///
64 | public class CloseAllMessage {
65 |
66 | readonly CancelEventArgs cancelEventArgs;
67 |
68 | ///
69 | /// Initializes a new instance of the CloseAllMessage class.
70 | ///
71 | /// An argument of the System.ComponentModel.CancelEventArgs type which can be used to cancel closing.
72 | public CloseAllMessage(CancelEventArgs cancelEventArgs) {
73 | this.cancelEventArgs = cancelEventArgs;
74 | }
75 |
76 | ///
77 | /// Used to cancel closing and check whether the closing has already been cancelled.
78 | ///
79 | public bool Cancel {
80 | get { return cancelEventArgs.Cancel; }
81 | set { cancelEventArgs.Cancel = value; }
82 | }
83 | }
84 |
85 | public class DestroyOrphanedDocumentsMessage { }
86 |
87 | ///
88 | /// Used by the PeekCollectionViewModel to notify that DocumentsViewModel should navigate to the specified module.
89 | ///
90 | /// The navigation token type.
91 | public class NavigateMessage {
92 |
93 | ///
94 | /// Initializes a new instance of the NavigateMessage class.
95 | ///
96 | /// An object that is used to identify the module to which the DocumentsViewModel should navigate.
97 | public NavigateMessage(TNavigationToken token) {
98 | Token = token;
99 | }
100 |
101 | ///
102 | /// An object that is used to identify the module to which the DocumentsViewModel should navigate.
103 | ///
104 | public TNavigationToken Token { get; private set; }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/ViewModel/PeekCollectionViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.ComponentModel.DataAnnotations;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Linq.Expressions;
7 | using DevExpress.Mvvm;
8 | using DevExpress.Mvvm.POCO;
9 | using DevExpress.Mvvm.DataAnnotations;
10 | using MVVMExpenses.Common.Utils;
11 | using MVVMExpenses.Common.DataModel;
12 |
13 | namespace MVVMExpenses.Common.ViewModel {
14 | ///
15 | /// A POCO view model exposing a read-only collection of entities of a given type. It is designed for quick navigation between collection views.
16 | /// This is a partial class that provides an extension point to add custom properties, commands and override methods without modifying the auto-generated code.
17 | ///
18 | /// A navigation token type.
19 | /// An entity type.
20 | /// A primary key value type.
21 | /// A unit of work type.
22 | public partial class PeekCollectionViewModel : CollectionViewModelBase
23 | where TEntity : class
24 | where TUnitOfWork : IUnitOfWork {
25 |
26 | ///
27 | /// Creates a new instance of PeekCollectionViewModel as a POCO view model.
28 | ///
29 | /// Identifies the module that is the navigation target.
30 | /// A factory that is used to create a unit of work instance.
31 | /// A function that returns a repository representing entities of a given type.
32 | /// An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data.
33 | public static PeekCollectionViewModel Create(
34 | TNavigationToken navigationToken,
35 | IUnitOfWorkFactory unitOfWorkFactory,
36 | Func> getRepositoryFunc,
37 | Func, IQueryable> projection = null) {
38 | return ViewModelSource.Create(() => new PeekCollectionViewModel(navigationToken, unitOfWorkFactory, getRepositoryFunc, projection));
39 | }
40 |
41 | TNavigationToken navigationToken;
42 | TEntity pickedEntity;
43 |
44 | ///
45 | /// Initializes a new instance of the PeekCollectionViewModel class.
46 | /// This constructor is declared protected to avoid an undesired instantiation of the PeekCollectionViewModel type without the POCO proxy factory.
47 | ///
48 | /// Identifies the module that is the navigation target.
49 | /// A factory that is used to create a unit of work instance.
50 | /// A function that returns a repository representing entities of a given type.
51 | /// An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data.
52 | protected PeekCollectionViewModel(
53 | TNavigationToken navigationToken,
54 | IUnitOfWorkFactory unitOfWorkFactory,
55 | Func> getRepositoryFunc,
56 | Func, IQueryable> projection = null
57 | ) : base(unitOfWorkFactory, getRepositoryFunc, projection, null, null, true) {
58 | this.navigationToken = navigationToken;
59 | }
60 |
61 | ///
62 | /// Navigates to the corresponding collection view and selects the given entity.
63 | /// Since PeekCollectionViewModel is a POCO view model, an instance of this class will also expose the NavigateCommand property that can be used as a binding source in views.
64 | ///
65 | /// An entity to select within the collection view.
66 | [Display(AutoGenerateField = false)]
67 | public void Navigate(TEntity projectionEntity) {
68 | pickedEntity = projectionEntity;
69 | SendSelectEntityMessage();
70 | Messenger.Default.Send(new NavigateMessage(navigationToken), navigationToken);
71 | }
72 |
73 | ///
74 | /// Determines if a navigation to corresponding collection view can be performed.
75 | /// Since PeekCollectionViewModel is a POCO view model, this method will be used as a CanExecute callback for NavigateCommand.
76 | ///
77 | /// An entity to select in the collection view.
78 | public bool CanNavigate(TEntity projectionEntity) {
79 | return projectionEntity != null;
80 | }
81 |
82 | protected override void OnInitializeInRuntime() {
83 | base.OnInitializeInRuntime();
84 | Messenger.Default.Register(this, x => SendSelectEntityMessage());
85 | }
86 |
87 | void SendSelectEntityMessage() {
88 | if(IsLoaded && pickedEntity != null)
89 | Messenger.Default.Send(new SelectEntityMessage(CreateRepository().GetProjectionPrimaryKey(pickedEntity)));
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Common/ViewModel/ViewModelLogicalLayoutHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using DevExpress.Mvvm;
7 |
8 | namespace MVVMExpenses.Common.ViewModel {
9 | public class ViewModelLogicalLayoutHelper {
10 | public static string PersistentLogicalLayout {
11 | get { return LayoutSettings.Default.LogicalLayout; }
12 | set { LayoutSettings.Default.LogicalLayout = value; }
13 | }
14 | static Dictionary persistentViewsLayout;
15 | public static Dictionary PersistentViewsLayout {
16 | get {
17 | if(persistentViewsLayout == null) {
18 | persistentViewsLayout = LogicalLayoutSerializationHelper.Deserialize(LayoutSettings.Default.ViewsLayout);
19 | }
20 | return persistentViewsLayout;
21 | }
22 | }
23 | public static void SaveLayout() {
24 | LayoutSettings.Default.ViewsLayout = LogicalLayoutSerializationHelper.Serialize(PersistentViewsLayout);
25 | LayoutSettings.Default.Save();
26 | }
27 | public static void ResetLayout() {
28 | PersistentViewsLayout.Clear();
29 | PersistentLogicalLayout = null;
30 | SaveLayout();
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Data/Expenses.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevExpress-Examples/winforms-mvvm-expenses-app/70a139e6d5909c97e63090201977325d1be58b9a/CS/MVVMExpenses/Data/Expenses.sqlite3
--------------------------------------------------------------------------------
/CS/MVVMExpenses/DataBase/DbContext.cs:
--------------------------------------------------------------------------------
1 | using System.Data.Entity;
2 | using MVVMExpenses.DataModels;
3 |
4 | namespace MVVMExpenses.DataBase {
5 | [DbConfigurationType(typeof(MVVMExpenses.Common.DataModel.EntityFramework.MyDbSQLiteConfiguration))]
6 | public class MyDbContext : System.Data.Entity.DbContext {
7 | static MyDbContext() {
8 | Database.SetInitializer(null);
9 | }
10 | public DbSet Accounts { get; set; }
11 | public DbSet Categories { get; set; }
12 | public DbSet Transactions { get; set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Models/Account.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.ComponentModel.DataAnnotations;
7 |
8 | namespace MVVMExpenses.DataModels {
9 | public class Account {
10 | [Key, Display(AutoGenerateField = false)]
11 | public long ID { get; set; }
12 | [Required, StringLength(30, MinimumLength = 4)]
13 | [Display(Name = "ACCOUNT")]
14 | public string Name { get; set; }
15 | [DataType(DataType.Currency)]
16 | [Display(Name = "AMOUNT")]
17 | public decimal Amount { get; set; }
18 | public override string ToString() {
19 | return Name + " (" + Amount.ToString("C") + ")";
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Models/Category.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.ComponentModel.DataAnnotations;
7 |
8 | namespace MVVMExpenses.DataModels {
9 | public class Category {
10 | [Key, Display(AutoGenerateField = false)]
11 | public long ID { get; set; }
12 | [Required, StringLength(30, MinimumLength = 5)]
13 | [Display(Name = "CATEGORY")]
14 | public string Name { get; set; }
15 | [EnumDataType(typeof(TransactionType))]
16 | [Display(Name = "TRANSACTION TYPE")]
17 | public TransactionType Type { get; set; }
18 | public override string ToString() {
19 | return Name + " (" + Type.ToString() + ")";
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Models/CredentialsSource.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using DevExpress.Mvvm.POCO;
3 | using MVVMExpenses.Models;
4 |
5 | namespace MVVMExpenses.ViewModels
6 | {
7 | //
8 | // TODO - your implementation
9 | static class CredentialsSource {
10 | static System.Collections.Hashtable credentials;
11 | static CredentialsSource() {
12 | credentials = new System.Collections.Hashtable();
13 | credentials.Add("Guest", GetHash(null));
14 | credentials.Add("John", GetHash("qwerty"));
15 | credentials.Add("Administrator", GetHash("admin"));
16 | credentials.Add("Mary", GetHash("12345"));
17 | }
18 | internal static bool Check(string login, string pwd) {
19 | return object.Equals(credentials[login], GetHash(pwd));
20 | }
21 | static object GetHash(string password) {
22 | return password;
23 | }
24 | internal static System.Collections.Generic.IEnumerable GetUserNames() {
25 | foreach(string item in credentials.Keys)
26 | yield return item;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Models/MyDbContextDataModel/IMyDbContextUnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Data;
4 | using System.Data.Entity;
5 | using System.Linq.Expressions;
6 | using System.Collections.Generic;
7 | using MVVMExpenses.Common.Utils;
8 | using MVVMExpenses.Common.DataModel;
9 | using MVVMExpenses.Common.DataModel.EntityFramework;
10 | using MVVMExpenses.DataBase;
11 | using MVVMExpenses.DataModels;
12 |
13 | namespace MVVMExpenses.Models.MyDbContextDataModel {
14 | ///
15 | /// IMyDbContextUnitOfWork extends the IUnitOfWork interface with repositories representing specific entities.
16 | ///
17 | public interface IMyDbContextUnitOfWork : IUnitOfWork {
18 |
19 | ///
20 | /// The Account entities repository.
21 | ///
22 | IRepository Accounts { get; }
23 |
24 | ///
25 | /// The Category entities repository.
26 | ///
27 | IRepository Categories { get; }
28 |
29 | ///
30 | /// The Transaction entities repository.
31 | ///
32 | IRepository Transactions { get; }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Models/MyDbContextDataModel/MyDbContextUnitOfWork.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Data;
4 | using System.Data.Entity;
5 | using System.Linq.Expressions;
6 | using System.Collections.Generic;
7 | using MVVMExpenses.Common.Utils;
8 | using MVVMExpenses.Common.DataModel;
9 | using MVVMExpenses.Common.DataModel.EntityFramework;
10 | using MVVMExpenses.DataBase;
11 | using MVVMExpenses.DataModels;
12 | using DevExpress.XtraBars;
13 |
14 | namespace MVVMExpenses.Models.MyDbContextDataModel {
15 | ///
16 | /// A MyDbContextUnitOfWork instance that represents the run-time implementation of the IMyDbContextUnitOfWork interface.
17 | ///
18 | public class MyDbContextUnitOfWork : DbUnitOfWork, IMyDbContextUnitOfWork {
19 |
20 | public MyDbContextUnitOfWork(Func contextFactory)
21 | : base(contextFactory) {
22 | }
23 |
24 | IRepository IMyDbContextUnitOfWork.Accounts {
25 | get { return GetRepository(x => x.Set(), x => x.ID); }
26 | }
27 |
28 | IRepository IMyDbContextUnitOfWork.Categories {
29 | get { return GetRepository(x => x.Set(), x => x.ID); }
30 | }
31 |
32 | IRepository IMyDbContextUnitOfWork.Transactions {
33 | get { return GetRepository(x => x.Set(), x => x.ID); }
34 | }
35 |
36 | BarHeaderItem bhi = new BarHeaderItem() { Width = 100 };
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Models/MyDbContextDataModel/UnitOfWorkSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Data;
4 | using System.Data.Entity;
5 | using System.Linq.Expressions;
6 | using System.Collections.Generic;
7 | using MVVMExpenses.Common.Utils;
8 | using MVVMExpenses.Common.DataModel;
9 | using MVVMExpenses.Common.DataModel.EntityFramework;
10 | using MVVMExpenses.DataBase;
11 | using MVVMExpenses.DataModels;
12 | using DevExpress.Mvvm;
13 | using System.Collections;
14 | using System.ComponentModel;
15 | using DevExpress.Data.Linq;
16 | using DevExpress.Data.Linq.Helpers;
17 | using DevExpress.Data.Async.Helpers;
18 |
19 | namespace MVVMExpenses.Models.MyDbContextDataModel {
20 | ///
21 | /// Provides methods to obtain the relevant IUnitOfWorkFactory.
22 | ///
23 | public static class UnitOfWorkSource {
24 |
25 | ///
26 | /// Returns the IUnitOfWorkFactory implementation.
27 | ///
28 | public static IUnitOfWorkFactory GetUnitOfWorkFactory() {
29 | return new DbUnitOfWorkFactory(() => new MyDbContextUnitOfWork(() => new MyDbContext()));
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Models/Transaction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.ComponentModel.DataAnnotations;
7 |
8 | namespace MVVMExpenses.DataModels {
9 | public enum TransactionType {
10 | Expense,
11 | Income
12 | }
13 | public class Transaction {
14 | [Key, Display(AutoGenerateField = false)]
15 | public long ID { get; set; }
16 | [Display(AutoGenerateField = false)]
17 | public long AccountID { get; set; }
18 | [Display(Name = "ACCOUNT")]
19 | public virtual Account Account { get; set; }
20 | [Display(AutoGenerateField = false)]
21 | public long CategoryID { get; set; }
22 | [Display(Name = "CATEGORY")]
23 | public virtual Category Category { get; set; }
24 | [DataType(DataType.Date)]
25 | [Display(Name = "DATE")]
26 | public DateTime Date { get; set; }
27 | [DataType(DataType.Currency)]
28 | [Display(Name = "AMOUNT")]
29 | public decimal Amount { get; set; }
30 | [DataType(DataType.MultilineText)]
31 | [Display(Name = "COMMENT")]
32 | public string Comment { get; set; }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Models/User.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace MVVMExpenses.Models {
9 | public class User {
10 | public string Login { get; set; }
11 | public string Password { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 | using DevExpress.Skins;
7 |
8 | namespace MVVMExpenses {
9 | static class Program {
10 | ///
11 | /// The main entry point for the application.
12 | ///
13 | [STAThread]
14 | static void Main() {
15 | SkinManager.EnableFormSkins();
16 | Application.EnableVisualStyles();
17 | Application.SetCompatibleTextRenderingDefault(false);
18 | Application.Run(new MainView());
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("MVVMExpenses")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("MVVMExpenses")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("f4f8f877-60af-42a1-a36e-a6d8ddc2d7cc")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Properties/DataSources/MVVMExpenses.DataModels.Account.datasource:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | MVVMExpenses.DataModels.Account, MVVMExpenses, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
10 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Properties/DataSources/MVVMExpenses.DataModels.Category.datasource:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | MVVMExpenses.DataModels.Category, MVVMExpenses, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
10 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Properties/DataSources/MVVMExpenses.DataModels.Transaction.datasource:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | MVVMExpenses.DataModels.Transaction, MVVMExpenses, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
10 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Properties/DataSources/MVVMExpenses.Models.SampleUserList.datasource:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18052
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace MVVMExpenses.Properties {
12 |
13 |
14 | ///
15 | /// A strongly-typed resource class, for looking up localized strings, etc.
16 | ///
17 | // This class was auto-generated by the StronglyTypedResourceBuilder
18 | // class via a tool like ResGen or Visual Studio.
19 | // To add or remove a member, edit your .ResX file then rerun ResGen
20 | // with the /str option, or rebuild your VS project.
21 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
22 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
23 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
24 | internal class Resources {
25 |
26 | private static global::System.Resources.ResourceManager resourceMan;
27 |
28 | private static global::System.Globalization.CultureInfo resourceCulture;
29 |
30 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
31 | internal Resources() {
32 | }
33 |
34 | ///
35 | /// Returns the cached ResourceManager instance used by this class.
36 | ///
37 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
38 | internal static global::System.Resources.ResourceManager ResourceManager {
39 | get {
40 | if((resourceMan == null)) {
41 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MVVMExpenses.Properties.Resources", typeof(Resources).Assembly);
42 | resourceMan = temp;
43 | }
44 | return resourceMan;
45 | }
46 | }
47 |
48 | ///
49 | /// Overrides the current thread's CurrentUICulture property for all
50 | /// resource lookups using this strongly typed resource class.
51 | ///
52 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
53 | internal static global::System.Globalization.CultureInfo Culture {
54 | get {
55 | return resourceCulture;
56 | }
57 | set {
58 | resourceCulture = value;
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18052
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace MVVMExpenses.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/ViewModels/Account/AccountCollectionViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using DevExpress.Mvvm.POCO;
4 | using MVVMExpenses.Common.Utils;
5 | using MVVMExpenses.Models.MyDbContextDataModel;
6 | using MVVMExpenses.Common.DataModel;
7 | using MVVMExpenses.DataModels;
8 | using MVVMExpenses.DataBase;
9 | using MVVMExpenses.Common.ViewModel;
10 | using System.Collections.Generic;
11 |
12 | namespace MVVMExpenses.Models.ViewModels {
13 | ///
14 | /// Represents the Accounts collection view model.
15 | ///
16 | public partial class AccountCollectionViewModel : CollectionViewModel {
17 |
18 | ///
19 | /// Creates a new instance of AccountCollectionViewModel as a POCO view model.
20 | ///
21 | /// A factory used to create a unit of work instance.
22 | public static AccountCollectionViewModel Create(IUnitOfWorkFactory unitOfWorkFactory = null) {
23 | return ViewModelSource.Create(() => new AccountCollectionViewModel(unitOfWorkFactory));
24 | }
25 |
26 | ///
27 | /// Initializes a new instance of the AccountCollectionViewModel class.
28 | /// This constructor is declared protected to avoid undesired instantiation of the AccountCollectionViewModel type without the POCO proxy factory.
29 | ///
30 | /// A factory used to create a unit of work instance.
31 | protected AccountCollectionViewModel(IUnitOfWorkFactory unitOfWorkFactory = null)
32 | : base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Accounts) {
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/ViewModels/Account/AccountViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using System.Collections.Generic;
5 | using System.Collections.ObjectModel;
6 | using DevExpress.Mvvm;
7 | using DevExpress.Mvvm.POCO;
8 | using MVVMExpenses.Common.Utils;
9 | using MVVMExpenses.Models.MyDbContextDataModel;
10 | using MVVMExpenses.Common.DataModel;
11 | using MVVMExpenses.DataModels;
12 | using MVVMExpenses.DataBase;
13 | using MVVMExpenses.Common.ViewModel;
14 |
15 | namespace MVVMExpenses.Models.ViewModels {
16 | ///
17 | /// Represents the single Account object view model.
18 | ///
19 | public partial class AccountViewModel : SingleObjectViewModel {
20 |
21 | ///
22 | /// Creates a new instance of AccountViewModel as a POCO view model.
23 | ///
24 | /// A factory used to create a unit of work instance.
25 | public static AccountViewModel Create(IUnitOfWorkFactory unitOfWorkFactory = null) {
26 | return ViewModelSource.Create(() => new AccountViewModel(unitOfWorkFactory));
27 | }
28 |
29 | ///
30 | /// Initializes a new instance of the AccountViewModel class.
31 | /// This constructor is declared protected to avoid undesired instantiation of the AccountViewModel type without the POCO proxy factory.
32 | ///
33 | /// A factory used to create a unit of work instance.
34 | protected AccountViewModel(IUnitOfWorkFactory unitOfWorkFactory = null)
35 | : base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Accounts, x => x.Name) {
36 | }
37 |
38 | public CollectionViewModel AccountTransactionDetails {
39 | get { return GetDetailsCollectionViewModel((AccountViewModel x) => x.AccountTransactionDetails, x => x.Transactions, x => x.AccountID, (x, key) => x.AccountID = key); }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/ViewModels/Category/CategoryCollectionViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using DevExpress.Mvvm.POCO;
4 | using MVVMExpenses.Common.Utils;
5 | using MVVMExpenses.Models.MyDbContextDataModel;
6 | using MVVMExpenses.Common.DataModel;
7 | using MVVMExpenses.DataModels;
8 | using MVVMExpenses.DataBase;
9 | using MVVMExpenses.Common.ViewModel;
10 |
11 | namespace MVVMExpenses.Models.ViewModels {
12 | ///
13 | /// Represents the Categories collection view model.
14 | ///
15 | public partial class CategoryCollectionViewModel : CollectionViewModel {
16 |
17 | ///
18 | /// Creates a new instance of CategoryCollectionViewModel as a POCO view model.
19 | ///
20 | /// A factory used to create a unit of work instance.
21 | public static CategoryCollectionViewModel Create(IUnitOfWorkFactory unitOfWorkFactory = null) {
22 | return ViewModelSource.Create(() => new CategoryCollectionViewModel(unitOfWorkFactory));
23 | }
24 |
25 | ///
26 | /// Initializes a new instance of the CategoryCollectionViewModel class.
27 | /// This constructor is declared protected to avoid undesired instantiation of the CategoryCollectionViewModel type without the POCO proxy factory.
28 | ///
29 | /// A factory used to create a unit of work instance.
30 | protected CategoryCollectionViewModel(IUnitOfWorkFactory unitOfWorkFactory = null)
31 | : base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Categories) {
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/ViewModels/Category/CategoryViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using System.Collections.Generic;
5 | using System.Collections.ObjectModel;
6 | using DevExpress.Mvvm;
7 | using DevExpress.Mvvm.POCO;
8 | using MVVMExpenses.Common.Utils;
9 | using MVVMExpenses.Models.MyDbContextDataModel;
10 | using MVVMExpenses.Common.DataModel;
11 | using MVVMExpenses.DataModels;
12 | using MVVMExpenses.DataBase;
13 | using MVVMExpenses.Common.ViewModel;
14 |
15 | namespace MVVMExpenses.Models.ViewModels {
16 | ///
17 | /// Represents the single Category object view model.
18 | ///
19 | public partial class CategoryViewModel : SingleObjectViewModel {
20 |
21 | ///
22 | /// Creates a new instance of CategoryViewModel as a POCO view model.
23 | ///
24 | /// A factory used to create a unit of work instance.
25 | public static CategoryViewModel Create(IUnitOfWorkFactory unitOfWorkFactory = null) {
26 | return ViewModelSource.Create(() => new CategoryViewModel(unitOfWorkFactory));
27 | }
28 |
29 | ///
30 | /// Initializes a new instance of the CategoryViewModel class.
31 | /// This constructor is declared protected to avoid undesired instantiation of the CategoryViewModel type without the POCO proxy factory.
32 | ///
33 | /// A factory used to create a unit of work instance.
34 | protected CategoryViewModel(IUnitOfWorkFactory unitOfWorkFactory = null)
35 | : base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Categories, x => x.Name) {
36 | }
37 |
38 | public CollectionViewModel CategoryTransactionDetails {
39 | get { return GetDetailsCollectionViewModel((CategoryViewModel x) => x.CategoryTransactionDetails, x => x.Transactions, x => x.CategoryID, (x, key) => x.CategoryID = key); }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/ViewModels/LoginViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using DevExpress.Mvvm.POCO;
3 | using MVVMExpenses.Models;
4 |
5 | namespace MVVMExpenses.ViewModels {
6 | public class LoginViewModel {
7 | public IEnumerable LookUpUsers {
8 | get { return CredentialsSource.GetUserNames(); }
9 | }
10 | public virtual User CurrentUser { get; set; }
11 | public bool IsCurrentUserCredentialsValid { get; private set; }
12 | //
13 | [DevExpress.Mvvm.DataAnnotations.Command(false)]
14 | public void Init() {
15 | this.CurrentUser = new User();
16 | }
17 | public void Update() {
18 | IsCurrentUserCredentialsValid = CredentialsSource.Check(CurrentUser.Login, CurrentUser.Password);
19 | }
20 | public static LoginViewModel Create() {
21 | return ViewModelSource.Create();
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/ViewModels/MyDbContextViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.ComponentModel;
5 | using DevExpress.Mvvm;
6 | using DevExpress.Mvvm.POCO;
7 | using MVVMExpenses.Common.DataModel;
8 | using MVVMExpenses.Common.ViewModel;
9 | using MVVMExpenses.Models.MyDbContextDataModel;
10 | using MVVMExpenses.DataBase;
11 | using MVVMExpenses.DataModels;
12 | using MVVMExpenses.ViewModels;
13 |
14 | namespace MVVMExpenses.Models.ViewModels {
15 | ///
16 | /// Represents the root POCO view model for the MyDbContext data model.
17 | ///
18 | public partial class MyDbContextViewModel : DocumentsViewModel {
19 | const string TablesGroup = "Tables";
20 |
21 | const string ViewsGroup = "Views";
22 |
23 | ///
24 | /// Creates a new instance of MyDbContextViewModel as a POCO view model.
25 | ///
26 | public static MyDbContextViewModel Create() {
27 | return ViewModelSource.Create(() => new MyDbContextViewModel());
28 | }
29 |
30 | ///
31 | /// Initializes a new instance of the MyDbContextViewModel class.
32 | /// This constructor is declared protected to avoid undesired instantiation of the MyDbContextViewModel type without the POCO proxy factory.
33 | ///
34 | //protected MyDbContextViewModel()
35 | // : base(UnitOfWorkSource.GetUnitOfWorkFactory()) {
36 | //}
37 |
38 | protected override MyDbContextModuleDescription[] CreateModules() {
39 | return new MyDbContextModuleDescription[] {
40 | new MyDbContextModuleDescription("Accounts", "AccountCollectionView", TablesGroup, GetPeekCollectionViewModelFactory(x => x.Accounts)),
41 | new MyDbContextModuleDescription("Categories", "CategoryCollectionView", TablesGroup, GetPeekCollectionViewModelFactory(x => x.Categories)),
42 | new MyDbContextModuleDescription("Transactions", "TransactionCollectionView", TablesGroup, GetPeekCollectionViewModelFactory(x => x.Transactions)),
43 | };
44 | }
45 |
46 |
47 |
48 | }
49 |
50 | public partial class MyDbContextModuleDescription : ModuleDescription {
51 | public MyDbContextModuleDescription(string title, string documentType, string group, Func peekCollectionViewModelFactory = null)
52 | : base(title, documentType, group, peekCollectionViewModelFactory) {
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/ViewModels/MyDbContextViewModel.partial.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows;
3 | using DevExpress.Mvvm;
4 | using DevExpress.Mvvm.POCO;
5 | using DevExpress.Utils.MVVM;
6 | using MVVMExpenses.Models.MyDbContextDataModel;
7 | using MVVMExpenses.ViewModels;
8 |
9 | namespace MVVMExpenses.Models.ViewModels {
10 | public partial class MyDbContextViewModel {
11 | LoginViewModel loginViewModel;
12 |
13 | protected MyDbContextViewModel()
14 | : base(UnitOfWorkSource.GetUnitOfWorkFactory()) {
15 | loginViewModel = LoginViewModel.Create();
16 | loginViewModel.SetParentViewModel(this);
17 | }
18 | protected IDialogService DialogService {
19 | get { return this.GetService(); }
20 | }
21 | protected IMessageBoxService MessageService {
22 | get { return this.GetService(); }
23 | }
24 |
25 | public override void OnLoaded(MyDbContextModuleDescription module) {
26 | base.OnLoaded(module);
27 | Login();
28 | }
29 | public override void OnClosing(CancelEventArgs cancelEventArgs) {
30 | base.OnClosing(cancelEventArgs);
31 | if(!cancelEventArgs.Cancel) {
32 | if(State == AppState.Authorized && MessageService.ShowMessage("Do you really want to close the application?", "Confirm", MessageButton.YesNo) == MessageResult.No)
33 | cancelEventArgs.Cancel = true;
34 | }
35 | }
36 | //
37 | public virtual AppState State { get; set; }
38 | // Shows the Login View
39 | public void Login() {
40 | OnLogin(DialogService.ShowDialog(MessageButton.OKCancel, "Please enter you credentials", "LoginView", loginViewModel));
41 | }
42 | public void Logout() {
43 | State = AppState.ExitQueued;
44 | System.Diagnostics.Process.Start(System.Windows.Forms.Application.ExecutablePath);
45 | }
46 | public bool CanLogout() {
47 | return State == AppState.Authorized;
48 | }
49 | //Occurs whenever the end-user clicks a dialog button
50 | void OnLogin(MessageResult result) {
51 | if(result == MessageResult.Cancel)
52 | State = AppState.ExitQueued;
53 | else {
54 | if(loginViewModel.IsCurrentUserCredentialsValid)
55 | State = AppState.Authorized;
56 | else
57 | Login();
58 | }
59 | }
60 | protected void OnStateChanged() {
61 | this.RaiseCanExecuteChanged(x => x.Logout());
62 | if(State == AppState.Authorized)
63 | Messenger.Default.Send(loginViewModel.CurrentUser.Login);
64 | else
65 | Messenger.Default.Send(string.Empty);
66 | }
67 | }
68 |
69 | public enum AppState {
70 | NotAuthorized,
71 | Authorized,
72 | ExitQueued
73 | }
74 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/ViewModels/Transaction/TransactionCollectionViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using DevExpress.Mvvm.POCO;
4 | using MVVMExpenses.Common.Utils;
5 | using MVVMExpenses.Models.MyDbContextDataModel;
6 | using MVVMExpenses.Common.DataModel;
7 | using MVVMExpenses.DataModels;
8 | using MVVMExpenses.DataBase;
9 | using MVVMExpenses.Common.ViewModel;
10 |
11 | namespace MVVMExpenses.Models.ViewModels {
12 | ///
13 | /// Represents the Transactions collection view model.
14 | ///
15 | public partial class TransactionCollectionViewModel : CollectionViewModel {
16 |
17 | ///
18 | /// Creates a new instance of TransactionCollectionViewModel as a POCO view model.
19 | ///
20 | /// A factory used to create a unit of work instance.
21 | public static TransactionCollectionViewModel Create(IUnitOfWorkFactory unitOfWorkFactory = null) {
22 | return ViewModelSource.Create(() => new TransactionCollectionViewModel(unitOfWorkFactory));
23 | }
24 |
25 | ///
26 | /// Initializes a new instance of the TransactionCollectionViewModel class.
27 | /// This constructor is declared protected to avoid undesired instantiation of the TransactionCollectionViewModel type without the POCO proxy factory.
28 | ///
29 | /// A factory used to create a unit of work instance.
30 | protected TransactionCollectionViewModel(IUnitOfWorkFactory unitOfWorkFactory = null)
31 | : base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Transactions) {
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/ViewModels/Transaction/TransactionViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using System.Collections.Generic;
5 | using System.Collections.ObjectModel;
6 | using DevExpress.Mvvm;
7 | using DevExpress.Mvvm.POCO;
8 | using MVVMExpenses.Common.Utils;
9 | using MVVMExpenses.Models.MyDbContextDataModel;
10 | using MVVMExpenses.Common.DataModel;
11 | using MVVMExpenses.DataModels;
12 | using MVVMExpenses.DataBase;
13 | using MVVMExpenses.Common.ViewModel;
14 |
15 | namespace MVVMExpenses.Models.ViewModels {
16 | ///
17 | /// Represents the single Transaction object view model.
18 | ///
19 | public partial class TransactionViewModel : SingleObjectViewModel {
20 |
21 | ///
22 | /// Creates a new instance of TransactionViewModel as a POCO view model.
23 | ///
24 | /// A factory used to create a unit of work instance.
25 | public static TransactionViewModel Create(IUnitOfWorkFactory unitOfWorkFactory = null) {
26 | return ViewModelSource.Create(() => new TransactionViewModel(unitOfWorkFactory));
27 | }
28 |
29 | ///
30 | /// Initializes a new instance of the TransactionViewModel class.
31 | /// This constructor is declared protected to avoid undesired instantiation of the TransactionViewModel type without the POCO proxy factory.
32 | ///
33 | /// A factory used to create a unit of work instance.
34 | protected TransactionViewModel(IUnitOfWorkFactory unitOfWorkFactory = null)
35 | : base(unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(), x => x.Transactions, x => x.Comment) {
36 | }
37 |
38 | ///
39 | /// The view model that contains a look-up collection of Accounts for the corresponding navigation property in the view.
40 | ///
41 | public IEntitiesViewModel LookUpAccounts {
42 | get { return GetLookUpEntitiesViewModel((TransactionViewModel x) => x.LookUpAccounts, x => x.Accounts); }
43 | }
44 |
45 | ///
46 | /// The view model that contains a look-up collection of Categories for the corresponding navigation property in the view.
47 | ///
48 | public IEntitiesViewModel LookUpCategories {
49 | get { return GetLookUpEntitiesViewModel((TransactionViewModel x) => x.LookUpCategories, x => x.Categories); }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Views/Account/AccountsEditFormView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Data;
6 | using System.Text;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using DevExpress.XtraEditors;
11 | using MVVMExpenses.Models;
12 | using MVVMExpenses.Models.ViewModels;
13 | using DevExpress.XtraGrid.Views.Grid;
14 |
15 | namespace MVVMExpenses.Common.Views.Account {
16 | [DevExpress.Utils.MVVM.UI.ViewType("AccountView")]
17 | public partial class AccountsEditFormView : DevExpress.XtraEditors.XtraUserControl {
18 | public AccountsEditFormView() {
19 | InitializeComponent();
20 | if(!DesignMode) InitBindings();
21 | }
22 |
23 | void InitBindings() {
24 | var fluent = mvvmContext1.OfType();
25 | fluent.SetObjectDataSourceBinding(
26 | accountBindingSource, x => x.Entity, x => x.Update());
27 |
28 | fluent.SetBinding(
29 | gridControl1, gc => gc.DataSource, x => x.AccountTransactionDetails.Entities);
30 |
31 | ((GridView)gridControl1.MainView).OptionsBehavior.Editable = false;
32 | ((GridView)gridControl1.MainView).Columns["Account"].Visible = false;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Views/Account/AccountsView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Data;
6 | using System.Text;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using DevExpress.XtraEditors;
11 | using DevExpress.Utils.MVVM.Services;
12 | using MVVMExpenses.Models.ViewModels;
13 |
14 | namespace MVVMExpenses.Common.Views.Account {
15 | [DevExpress.Utils.MVVM.UI.ViewType("AccountCollectionView")]
16 | public partial class AccountsView : DevExpress.XtraEditors.XtraUserControl {
17 | public AccountsView() {
18 | InitializeComponent();
19 | if(!DesignMode)
20 | InitBindings();
21 | gridView1.OptionsBehavior.Editable = false;
22 | gridView1.OptionsSelection.MultiSelect = true;
23 | gridView1.OptionsSelection.MultiSelectMode = DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode.RowSelect;
24 | }
25 |
26 | void InitBindings() {
27 | var fluentAPI = mvvmContext1.OfType();
28 | fluentAPI.SetBinding(gridView1, gView => gView.LoadingPanelVisible, x => x.IsLoading);
29 | fluentAPI.SetBinding(gridControl1, gControl => gControl.DataSource, x => x.Entities);
30 |
31 | fluentAPI.WithEvent(gridView1, "FocusedRowObjectChanged")
32 | .SetBinding(x => x.SelectedEntity,
33 | args => args.Row as DataModels.Account,
34 | (gView, entity) => gView.FocusedRowHandle = gView.FindRow(entity));
35 | fluentAPI.WithEvent(gridView1, "RowCellClick")
36 | .EventToCommand(
37 | x => x.Edit(null), x => x.SelectedEntity,
38 | args => (args.Clicks == 2) && (args.Button == MouseButtons.Left));
39 |
40 | fluentAPI.WithEvent(gridView1, "SelectionChanged")
41 | .SetBinding(x => x.Selection, e => GetSelectedAccounts());
42 | }
43 |
44 | IEnumerable GetSelectedAccounts() {
45 | return gridView1.GetSelectedRows().Select(r => gridView1.GetRow(r) as MVVMExpenses.DataModels.Account);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Views/Category/CategoriesEditFormView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Data;
6 | using System.Text;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using DevExpress.XtraEditors;
11 | using MVVMExpenses.Models;
12 | using MVVMExpenses.Models.ViewModels;
13 | using DevExpress.XtraGrid.Views.Grid;
14 |
15 | namespace MVVMExpenses.Common.Views.Category {
16 | [DevExpress.Utils.MVVM.UI.ViewType("CategoryView")]
17 | public partial class CategoriesEditFormView : DevExpress.XtraEditors.XtraUserControl {
18 | public CategoriesEditFormView() {
19 | InitializeComponent();
20 | this.TypeImageComboBoxEdit.Properties.Items.AddEnum();
21 | if(!DesignMode) InitBindings();
22 | }
23 |
24 | void InitBindings() {
25 | var fluent = mvvmContext1.OfType();
26 | fluent.SetObjectDataSourceBinding(
27 | categoryBindingSource, x => x.Entity, x => x.Update());
28 |
29 | fluent.SetBinding(
30 | gridControl1, gc => gc.DataSource, x => x.CategoryTransactionDetails.Entities);
31 |
32 | ((GridView)gridControl1.MainView).OptionsBehavior.Editable = false;
33 | ((GridView)gridControl1.MainView).Columns["Category"].Visible = false;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Views/Category/CategoriesView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Data;
6 | using System.Text;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using DevExpress.XtraEditors;
11 | using DevExpress.Utils.MVVM.Services;
12 | using MVVMExpenses.Models.ViewModels;
13 |
14 | namespace MVVMExpenses.Common.Views.Category {
15 | [DevExpress.Utils.MVVM.UI.ViewType("CategoryCollectionView")]
16 | public partial class CategoriesView : DevExpress.XtraEditors.XtraUserControl {
17 | public CategoriesView() {
18 | InitializeComponent();
19 | if(!DesignMode)
20 | InitBindings();
21 | gridView1.OptionsBehavior.Editable = false;
22 | gridView1.OptionsSelection.MultiSelect = true;
23 | gridView1.OptionsSelection.MultiSelectMode = DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode.RowSelect;
24 | }
25 |
26 | void InitBindings() {
27 | var fluentAPI = mvvmContext1.OfType();
28 | fluentAPI.SetBinding(gridView1, gView => gView.LoadingPanelVisible, x => x.IsLoading);
29 | fluentAPI.SetBinding(gridControl1, gControl => gControl.DataSource, x => x.Entities);
30 |
31 | fluentAPI.WithEvent(gridView1, "FocusedRowObjectChanged")
32 | .SetBinding(x => x.SelectedEntity,
33 | args => args.Row as DataModels.Category,
34 | (gView, entity) => gView.FocusedRowHandle = gView.FindRow(entity));
35 | fluentAPI.WithEvent(gridView1, "RowCellClick")
36 | .EventToCommand(
37 | x => x.Edit(null), x => x.SelectedEntity,
38 | args => (args.Clicks == 2) && (args.Button == MouseButtons.Left));
39 |
40 | fluentAPI.WithEvent(gridView1, "SelectionChanged")
41 | .SetBinding(x => x.Selection, e => GetSelectedCategories());
42 | }
43 |
44 | IEnumerable GetSelectedCategories() {
45 | return gridView1.GetSelectedRows().Select(r => gridView1.GetRow(r) as MVVMExpenses.DataModels.Category);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Views/LoginView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Data;
6 | using System.Text;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using DevExpress.XtraEditors;
11 | using MVVMExpenses.ViewModels;
12 |
13 | namespace MVVMExpenses.Views {
14 | public partial class LoginView : DevExpress.XtraEditors.XtraUserControl {
15 | public LoginView() {
16 | InitializeComponent();
17 | PasswordTextEdit.Properties.PasswordChar = '*';
18 | }
19 |
20 | protected override void OnLoad(System.EventArgs e) {
21 | base.OnLoad(e);
22 | var fluentAPI = mvvmContext1.OfType();
23 | fluentAPI.SetObjectDataSourceBinding(userBindingSource,
24 | x => x.CurrentUser, x => x.Update());
25 |
26 |
27 | foreach(string item in mvvmContext1.GetViewModel().LookUpUsers)
28 | LoginTextEdit.Properties.Items.Add(item);
29 | fluentAPI.ViewModel.Init();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Views/MainView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Windows.Forms;
4 | using DevExpress.Mvvm;
5 | using DevExpress.XtraEditors;
6 | using MVVMExpenses.Models.ViewModels;
7 |
8 | namespace MVVMExpenses {
9 | public partial class MainView : XtraForm {
10 | public MainView() {
11 | InitializeComponent();
12 | this.Opacity = 0;
13 | if(!DesignMode)
14 | InitializeNavigation();
15 | ribbonControl1.Merge += ribbonControl1_Merge;
16 | }
17 | void ribbonControl1_Merge(object sender, DevExpress.XtraBars.Ribbon.RibbonMergeEventArgs e) {
18 | ribbonControl1.SelectedPage = e.MergedChild.SelectedPage;
19 | }
20 | void InitializeNavigation() {
21 | var fluentAPI = mvvmContext1.OfType();
22 | fluentAPI.BindCommand(biAccounts, (x, m) => x.Show(m), x => x.Modules[0]);
23 | fluentAPI.BindCommand(biCategories, (x, m) => x.Show(m), x => x.Modules[1]);
24 | fluentAPI.BindCommand(biTransactions, (x, m) => x.Show(m), x => x.Modules[2]);
25 | //
26 | fluentAPI.BindCommand(biLogout, x => x.Logout());
27 | //
28 | fluentAPI.WithEvent(this, "Load")
29 | .EventToCommand(x => x.OnLoaded(null), x => x.DefaultModule);
30 | fluentAPI.WithEvent(this, "FormClosing")
31 | .EventToCommand(x => x.OnClosing(null), new Func((args) => args));
32 | fluentAPI.SetTrigger(x => x.State, (state) =>
33 | {
34 | if(state == AppState.Authorized)
35 | Opacity = 1; /*Show Main Form*/
36 | if(state == AppState.ExitQueued)
37 | Close(); // exit the app;
38 | });
39 | Messenger.Default.Register(this, OnUserNameMessage);
40 | }
41 | void OnUserNameMessage(string userName) {
42 | if(string.IsNullOrEmpty(userName))
43 | this.Text = "Expenses Application";
44 | else
45 | this.Text = "Expenses Application - (" + userName + ")";
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Views/Transaction/TransactionsEditFormView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Data;
6 | using System.Text;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using DevExpress.XtraEditors;
11 | using MVVMExpenses.Models.ViewModels;
12 |
13 | namespace MVVMExpenses.Common.Views.Transaction {
14 | [DevExpress.Utils.MVVM.UI.ViewType("TransactionView")]
15 | public partial class TransactionsEditFormView : DevExpress.XtraEditors.XtraUserControl {
16 | public TransactionsEditFormView() {
17 | InitializeComponent();
18 | if(!DesignMode)
19 | InitBindings();
20 | }
21 |
22 | void InitBindings() {
23 | var fluent = mvvmContext1.OfType();
24 | fluent.SetObjectDataSourceBinding(
25 | bindingSource, x => x.Entity, x => x.Update());
26 | fluent.SetBinding(accountBindingSource,
27 | abs => abs.DataSource, x => x.LookUpAccounts.Entities);
28 | fluent.SetBinding(categoryBindingSource,
29 | cbs => cbs.DataSource, x => x.LookUpCategories.Entities);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/Views/Transaction/TransactionsView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Data;
6 | using System.Text;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using DevExpress.XtraEditors;
11 | using MVVMExpenses.Models.ViewModels;
12 | using DevExpress.XtraGrid.Views.Base;
13 | using DevExpress.XtraGrid.Views.Grid;
14 |
15 | namespace MVVMExpenses.Common.Views.Transaction {
16 | [DevExpress.Utils.MVVM.UI.ViewType("TransactionCollectionView")]
17 | public partial class TransactionsView : DevExpress.XtraEditors.XtraUserControl {
18 | public TransactionsView() {
19 | InitializeComponent();
20 | if(!DesignMode)
21 | InitBindings();
22 | gridView1.OptionsBehavior.Editable = false;
23 | gridView1.OptionsSelection.MultiSelect = true;
24 | gridView1.OptionsSelection.MultiSelectMode = DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode.RowSelect;
25 | }
26 |
27 | void InitBindings() {
28 | var fluentAPI = mvvmContext1.OfType();
29 | fluentAPI.SetBinding(gridView1, gView => gView.LoadingPanelVisible, x => x.IsLoading);
30 | fluentAPI.SetBinding(gridControl1, gControl => gControl.DataSource, x => x.Entities);
31 |
32 | fluentAPI.WithEvent(gridView1, "FocusedRowObjectChanged")
33 | .SetBinding(x => x.SelectedEntity,
34 | args => args.Row as DataModels.Transaction,
35 | (gView, entity) => gView.FocusedRowHandle = gView.FindRow(entity));
36 | fluentAPI.WithEvent(gridView1, "RowCellClick")
37 | .EventToCommand(
38 | x => x.Edit(null), x => x.SelectedEntity,
39 | args => (args.Clicks == 2) && (args.Button == MouseButtons.Left));
40 | fluentAPI.WithEvent(gridView1, "SelectionChanged")
41 | .SetBinding(x => x.Selection, e => GetSelectedCategories());
42 | }
43 |
44 | IEnumerable GetSelectedCategories() {
45 | return gridView1.GetSelectedRows().Select(r => gridView1.GetRow(r) as MVVMExpenses.DataModels.Transaction);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/CS/MVVMExpenses/sqlite/System.Data.SQLite.EF6.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevExpress-Examples/winforms-mvvm-expenses-app/70a139e6d5909c97e63090201977325d1be58b9a/CS/MVVMExpenses/sqlite/System.Data.SQLite.EF6.dll
--------------------------------------------------------------------------------
/CS/MVVMExpenses/sqlite/System.Data.SQLite.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevExpress-Examples/winforms-mvvm-expenses-app/70a139e6d5909c97e63090201977325d1be58b9a/CS/MVVMExpenses/sqlite/System.Data.SQLite.dll
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This code example is provided "as is" without warranty of any kind. Developer Express Inc ("DevExpress") disclaims all warranties,
2 | either express or implied, including the warranties of merchantability and fitness for a particular purpose.
3 |
4 | For licensing terms and conditions of DevExpress product(s) required for, or associated with the use of this code example,
5 | please refer to the applicable End-User License Agreement at https://www.devexpress.com/Support/licensingfaq.xml
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 |
2 | 
3 | [](https://supportcenter.devexpress.com/ticket/details/T254492)
4 | [](https://docs.devexpress.com/GeneralInformation/403183)
5 | [](#does-this-example-address-your-development-requirementsobjectives)
6 |
7 | # MVVM Expenses - Sample Application for WinForms
8 |
9 |
10 | **MVVM Expenses** is a sample money management application built with the DevExpress MVVM Framework. The application includes three modules, each bound to a related data source: "Accounts", "Categories", and "Transactions":
11 |
12 | * *Accounts* displays a list of user bank accounts.
13 | * *Categories* stores a list of transaction categories.
14 | * *Transactions* stores a list of all deposit and withdrawal operations. Each transaction references a specific Account and Category by their IDs.
15 |
16 | To log in, use one of the following credentials:
17 |
18 | * Administrator - admin
19 | * John - qwerty
20 | * Mary - 12345
21 | * Guest - *(no password set)*
22 |
23 | ## Documentation
24 |
25 | * [MVVM Step-by-Step Tutorials](https://documentation.devexpress.com/#WindowsForms/CustomDocument114101)
26 | * [DevExpress MVVM Framework (WinForms)](https://docs.devexpress.com/WindowsForms/113955/build-an-application/winforms-mvvm)
27 |
28 |
29 |
30 | ## Does this example address your development requirements/objectives?
31 |
32 | [
](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=winforms-mvvm-expenses-app&~~~was_helpful=yes) [
](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=winforms-mvvm-expenses-app&~~~was_helpful=no)
33 |
34 | (you will be redirected to DevExpress.com to submit your response)
35 |
36 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2012
3 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "MVVMExpenses", "MVVMExpenses\MVVMExpenses.vbproj", "{E7AE86FF-3BDC-43E1-A33A-63A6970D3670}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | Release|Any CPU = Release|Any CPU
9 | EndGlobalSection
10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
11 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
12 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Debug|Any CPU.Build.0 = Debug|Any CPU
13 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Release|Any CPU.ActiveCfg = Release|Any CPU
14 | {E7AE86FF-3BDC-43E1-A33A-63A6970D3670}.Release|Any CPU.Build.0 = Release|Any CPU
15 | EndGlobalSection
16 | GlobalSection(SolutionProperties) = preSolution
17 | HideSolutionNode = FALSE
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/AppIcon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevExpress-Examples/winforms-mvvm-expenses-app/70a139e6d5909c97e63090201977325d1be58b9a/VB/MVVMExpenses/AppIcon.ico
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/AppIcon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevExpress-Examples/winforms-mvvm-expenses-app/70a139e6d5909c97e63090201977325d1be58b9a/VB/MVVMExpenses/Common/AppIcon.ico
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/DataModel/DbExceptions.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Namespace Common.DataModel
4 | '''
5 | ''' The database-independent exception used in Data Layer and View Model Layer to handle database errors.
6 | '''
7 | Public Class DbException
8 | Inherits Exception
9 | Private _ErrorCaption As String
10 | Private _ErrorMessage As String
11 | '''
12 | ''' Initializes a new instance of the DbRepository class.
13 | '''
14 | ''' An error message text.
15 | ''' An error message caption text.
16 | ''' An underlying exception.
17 | Public Sub New(ByVal errorMessage As String, ByVal errorCaption As String, ByVal innerException As Exception)
18 | MyBase.New(innerException.Message, innerException)
19 | Me._ErrorMessage = errorMessage
20 | Me._ErrorCaption = errorCaption
21 | End Sub
22 | ''' The error message text.
23 | Public ReadOnly Property ErrorMessage As String
24 | Get
25 | Return _ErrorMessage
26 | End Get
27 | End Property
28 | ''' The error message caption text.
29 | Public ReadOnly Property ErrorCaption As String
30 | Get
31 | Return _ErrorCaption
32 | End Get
33 | End Property
34 | End Class
35 | End Namespace
36 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/DataModel/EntityFramework/DbExceptionsConverter.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Data.Entity.Infrastructure
3 | Imports System.Data.Entity.Validation
4 | Imports System.Linq
5 | Imports System.Text
6 | Namespace Common.DataModel.EntityFramework
7 | '''
8 | ''' Provides methods to convert Entity Framework exceptions to database-independent exceptions used in Data Layer and View Model Layer.
9 | '''
10 | Public Module DbExceptionsConverter
11 | '''
12 | ''' Converts System.Data.Entity.Infrastructure.DbUpdateException exception to database-independent DbException exception used in Data Layer and View Model Layer.
13 | '''
14 | ''' Exception to convert.
15 | Public Function Convert(ByVal exception As DbUpdateException) As DbException
16 | Dim originalException As Exception = exception
17 | While originalException.InnerException IsNot Nothing
18 | originalException = originalException.InnerException
19 | End While
20 | Return New DbException(originalException.Message, CommonResources.Exception_UpdateErrorCaption, exception)
21 | End Function
22 | '''
23 | ''' Converts System.Data.Entity.Validation.DbEntityValidationException exception to database-independent DbException exception used in Data Layer and View Model Layer.
24 | '''
25 | ''' Exception to convert.
26 | Public Function Convert(ByVal exception As DbEntityValidationException) As DbException
27 | Dim stringBuilder As StringBuilder = New StringBuilder()
28 | For Each validationResult As DbEntityValidationResult In exception.EntityValidationErrors
29 | For Each [error] As DbValidationError In validationResult.ValidationErrors
30 | If stringBuilder.Length > 0 Then
31 | stringBuilder.AppendLine()
32 | End If
33 | stringBuilder.Append([error].PropertyName + ": " + [error].ErrorMessage)
34 | Next
35 | Next
36 | Return New DbException(stringBuilder.ToString(), CommonResources.Exception_ValidationErrorCaption, exception)
37 | End Function
38 | End Module
39 | End Namespace
40 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/DataModel/EntityFramework/DbReadOnlyRepository.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Linq.Expressions
4 | Imports System.Data.Entity
5 | Imports System.Collections.Generic
6 | Imports System.Collections.ObjectModel
7 | Namespace Common.DataModel.EntityFramework
8 | '''
9 | ''' A DbReadOnlyRepository is a IReadOnlyRepository interface implementation representing the collection of all entities in the unit of work, or that can be queried from the database, of a given type.
10 | ''' DbReadOnlyRepository objects are created from a DbUnitOfWork using the GetReadOnlyRepository method.
11 | ''' DbReadOnlyRepository provides only read-only operations against entities of a given type.
12 | '''
13 | ''' Repository entity type.
14 | ''' DbContext type.
15 | Public Class DbReadOnlyRepository(Of TEntity As Class, TDbContext As DbContext)
16 | Inherits DbRepositoryQuery(Of TEntity)
17 | Implements IReadOnlyRepository(Of TEntity)
18 | Private ReadOnly _dbSetAccessor As Func(Of TDbContext, DbSet(Of TEntity))
19 | Private ReadOnly _unitOfWork As DbUnitOfWork(Of TDbContext)
20 | '''
21 | ''' Initializes a new instance of DbReadOnlyRepository class.
22 | '''
23 | ''' Owner unit of work that provides context for repository entities.
24 | ''' Function that returns DbSet entities from Entity Framework DbContext.
25 | Public Sub New(ByVal unitOfWork As DbUnitOfWork(Of TDbContext), ByVal dbSetAccessor As Func(Of TDbContext, DbSet(Of TEntity)))
26 | MyBase.New(Function() dbSetAccessor(unitOfWork.Context))
27 | Me._dbSetAccessor = dbSetAccessor
28 | Me._unitOfWork = unitOfWork
29 | End Sub
30 | Protected ReadOnly Property DbSet As DbSet(Of TEntity)
31 | Get
32 | Return _dbSetAccessor(_unitOfWork.Context)
33 | End Get
34 | End Property
35 | Protected ReadOnly Property Context As TDbContext
36 | Get
37 | Return _unitOfWork.Context
38 | End Get
39 | End Property
40 | Private ReadOnly Property UnitOfWork As IUnitOfWork Implements IReadOnlyRepository(Of TEntity).UnitOfWork
41 | Get
42 | Return _unitOfWork
43 | End Get
44 | End Property
45 | End Class
46 | '''
47 | ''' DbRepositoryQuery is an IRepositoryQuery interface implementation that is an extension of IQueryable designed to specify the related objects to include in query results.
48 | '''
49 | ''' An entity type.
50 | Public Class DbRepositoryQuery(Of TEntity As Class)
51 | Inherits RepositoryQueryBase(Of TEntity)
52 | Implements IRepositoryQuery(Of TEntity)
53 | '''
54 | ''' Initializes a new instance of the DesignTimeRepositoryQuery class.
55 | '''
56 | ''' A function that returns an IQueryable instance which is used by DbRepositoryQuery to perform queries.
57 | Public Sub New(ByVal getQueryable As Func(Of IQueryable(Of TEntity)))
58 | MyBase.New(getQueryable)
59 | End Sub
60 | Private Function Include(Of TProperty)(ByVal path As Expression(Of Func(Of TEntity, TProperty))) As IRepositoryQuery(Of TEntity) Implements IRepositoryQuery(Of TEntity).Include
61 | Return New DbRepositoryQuery(Of TEntity)(Function() Queryable.Include(path))
62 | End Function
63 | Private Function Where(ByVal predicate As Expression(Of Func(Of TEntity, Boolean))) As IRepositoryQuery(Of TEntity) Implements IRepositoryQuery(Of TEntity).Where
64 | Return New DbRepositoryQuery(Of TEntity)(Function() Queryable.Where(predicate))
65 | End Function
66 | End Class
67 | End Namespace
68 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/DataModel/EntityFramework/DbUnitOfWork.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.Data.Entity
4 | Imports System.Data.Entity.Validation
5 | Imports System.Data.Entity.Infrastructure
6 | Imports System.Linq
7 | Imports System.Linq.Expressions
8 | Namespace Common.DataModel.EntityFramework
9 | '''
10 | ''' A DbUnitOfWork instance represents the implementation of the Unit Of Work pattern
11 | ''' such that it can be used to query from a database and group together changes that will then be written back to the store as a unit.
12 | '''
13 | ''' DbContext type.
14 | Public MustInherit Class DbUnitOfWork(Of TContext As DbContext)
15 | Inherits UnitOfWorkBase
16 | Implements IUnitOfWork
17 | Private ReadOnly _context As Lazy(Of TContext)
18 | Public Sub New(ByVal contextFactory As Func(Of TContext))
19 | _context = New Lazy(Of TContext)(contextFactory)
20 | End Sub
21 | '''
22 | ''' Instance of underlying DbContext.
23 | '''
24 | Public ReadOnly Property Context As TContext
25 | Get
26 | Return _context.Value
27 | End Get
28 | End Property
29 | Private Sub SaveChanges() Implements IUnitOfWork.SaveChanges
30 | Try
31 | Context.SaveChanges()
32 | Catch ex As DbEntityValidationException
33 | Throw DbExceptionsConverter.Convert(ex)
34 | Catch ex As DbUpdateException
35 | Throw DbExceptionsConverter.Convert(ex)
36 | End Try
37 | End Sub
38 | Private Function HasChanges() As Boolean Implements IUnitOfWork.HasChanges
39 | Return Context.ChangeTracker.HasChanges()
40 | End Function
41 | Protected Function GetRepository(Of TEntity As Class, TPrimaryKey)(ByVal dbSetAccessor As Func(Of TContext, DbSet(Of TEntity)), ByVal getPrimaryKeyExpression As Expression(Of Func(Of TEntity, TPrimaryKey))) As IRepository(Of TEntity, TPrimaryKey)
42 | Return GetRepositoryCore(Of IRepository(Of TEntity, TPrimaryKey), TEntity)(Function() New DbRepository(Of TEntity, TPrimaryKey, TContext)(Me, dbSetAccessor, getPrimaryKeyExpression))
43 | End Function
44 | Protected Function GetReadOnlyRepository(Of TEntity As Class)(ByVal dbSetAccessor As Func(Of TContext, DbSet(Of TEntity))) As IReadOnlyRepository(Of TEntity)
45 | Return GetRepositoryCore(Of IReadOnlyRepository(Of TEntity), TEntity)(Function() New DbReadOnlyRepository(Of TEntity, TContext)(Me, dbSetAccessor))
46 | End Function
47 | End Class
48 | End Namespace
49 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/DataModel/EntityFramework/DbUnitOfWorkFactory.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Data
4 | Imports System.Data.Entity
5 | Imports System.Linq.Expressions
6 | Imports System.Collections.Generic
7 | Imports Common.Utils
8 | Imports Common.DataModel
9 | Imports DevExpress.Mvvm
10 | Imports System.Collections
11 | Imports System.ComponentModel
12 | Imports DevExpress.Data.Linq
13 | Imports DevExpress.Data.Linq.Helpers
14 | Imports DevExpress.Data.Async.Helpers
15 | Namespace Common.DataModel.EntityFramework
16 | Friend Class DbUnitOfWorkFactory(Of TUnitOfWork As IUnitOfWork)
17 | Implements IUnitOfWorkFactory(Of TUnitOfWork)
18 | Private _createUnitOfWork As Func(Of TUnitOfWork)
19 | Public Sub New(ByVal createUnitOfWork As Func(Of TUnitOfWork))
20 | Me._createUnitOfWork = createUnitOfWork
21 | End Sub
22 | Private Function CreateUnitOfWork() As TUnitOfWork Implements IUnitOfWorkFactory(Of TUnitOfWork).CreateUnitOfWork
23 | Return _createUnitOfWork()
24 | End Function
25 | Private Function CreateInstantFeedbackSource(Of TEntity As {Class, New}, TProjection As Class, TPrimaryKey)(ByVal getRepositoryFunc As Func(Of TUnitOfWork, IRepository(Of TEntity, TPrimaryKey)), ByVal projection As Func(Of IRepositoryQuery(Of TEntity), IQueryable(Of TProjection))) As IInstantFeedbackSource(Of TProjection) Implements IUnitOfWorkFactory(Of TUnitOfWork).CreateInstantFeedbackSource
26 | Dim threadSafeProperties = New TypeInfoProxied(TypeDescriptor.GetProperties(GetType(TProjection)), Nothing).UIDescriptors
27 | If projection Is Nothing Then
28 | projection = Function(x) TryCast(x, IQueryable(Of TProjection))
29 | End If
30 | Dim source = New EntityInstantFeedbackSource(Sub(e As GetQueryableEventArgs) e.QueryableSource = projection(getRepositoryFunc(_createUnitOfWork()))) With {.KeyExpression = getRepositoryFunc(_createUnitOfWork()).GetPrimaryKeyPropertyName()}
31 | Return New InstantFeedbackSource(Of TProjection)(source, threadSafeProperties)
32 | End Function
33 | End Class
34 | End Namespace
35 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/DataModel/EntityFramework/InstantFeedbackSource.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Data
4 | Imports System.Data.Entity
5 | Imports System.Linq.Expressions
6 | Imports System.Collections.Generic
7 | Imports Common.Utils
8 | Imports Common.DataModel
9 | Imports DevExpress.Mvvm
10 | Imports System.Collections
11 | Imports System.ComponentModel
12 | Imports DevExpress.Data.Linq
13 | Imports DevExpress.Data.Linq.Helpers
14 | Imports DevExpress.Data.Async.Helpers
15 | Namespace Common.DataModel.EntityFramework
16 | Friend Class InstantFeedbackSource(Of TEntity As Class)
17 | Implements IInstantFeedbackSource(Of TEntity)
18 | Private ReadOnly _source As EntityInstantFeedbackSource
19 | Private ReadOnly _threadSafeProperties As PropertyDescriptorCollection
20 | Public Sub New(ByVal source As EntityInstantFeedbackSource, ByVal threadSafeProperties As PropertyDescriptorCollection)
21 | Me._source = source
22 | Me._threadSafeProperties = threadSafeProperties
23 | End Sub
24 | Private ReadOnly Property ContainsListCollection As Boolean Implements IListSource.ContainsListCollection
25 | Get
26 | Return CType(_source, IListSource).ContainsListCollection
27 | End Get
28 | End Property
29 | Private Function GetList() As IList Implements IListSource.GetList
30 | Return CType(_source, IListSource).GetList()
31 | End Function
32 | Private Function GetPropertyValue(Of TProperty)(ByVal threadSafeProxy As Object, ByVal propertyExpression As Expression(Of Func(Of TEntity, TProperty))) As TProperty Implements IInstantFeedbackSource(Of TEntity).GetPropertyValue
33 | Dim propertyName = ExpressionHelper.GetPropertyName(propertyExpression)
34 | Dim threadSafeProperty = _threadSafeProperties(propertyName)
35 | Return CType(threadSafeProperty.GetValue(threadSafeProxy), TProperty)
36 | End Function
37 | Private Function IsLoadedProxy(ByVal threadSafeProxy As Object) As Boolean Implements IInstantFeedbackSource(Of TEntity).IsLoadedProxy
38 | Return TypeOf threadSafeProxy Is ReadonlyThreadSafeProxyForObjectFromAnotherThread
39 | End Function
40 | Private Sub Refresh() Implements IInstantFeedbackSource(Of TEntity).Refresh
41 | _source.Refresh()
42 | End Sub
43 | End Class
44 | End Namespace
45 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/DataModel/EntityState.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Namespace Common.DataModel
4 | '''
5 | ''' Represents the state of the entity relative to the unit of work.
6 | '''
7 | Public Enum EntityState
8 | '''
9 | ''' The object exists but is not being tracked.
10 | ''' An entity is in this state immediately after it has been created and before it is added to the unit of work.
11 | ''' An entity is also in this state after it has been removed from the unit of work by calling the IUnitOfWork.Detach method.
12 | '''
13 | Detached = 1
14 | '''
15 | ''' The object has not been modified since it was attached to the unit of work or since the last time that the IUnitOfWork.SaveChanges method was called.
16 | '''
17 | Unchanged = 2
18 | '''
19 | ''' The object is new, has been added to the unit of work, and the IUnitOfWork.SaveChanges method has not been called.
20 | ''' After the changes are saved, the object state changes to Unchanged.
21 | '''
22 | Added = 4
23 | '''
24 | ''' The object has been deleted from the unit of work. After the changes are saved, the object state changes to Detached.
25 | '''
26 | Deleted = 8
27 | '''
28 | ''' One of the scalar properties on the object has been modified and the IUnitOfWork.SaveChanges method has not been called.
29 | ''' After the changes are saved, the object state changes to Unchanged.
30 | '''
31 | Modified = 16
32 | End Enum
33 | End Namespace
34 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/DataModel/IUnitOfWork.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.ComponentModel
3 | Imports System.Linq
4 | Imports System.Linq.Expressions
5 | Namespace Common.DataModel
6 | '''
7 | ''' The IUnitOfWork interface represents the Unit Of Work pattern
8 | ''' such that it can be used to query from a database and group together changes that will then be written back to the store as a unit.
9 | '''
10 | Public Interface IUnitOfWork
11 | '''
12 | ''' Saves all changes made in this unit of work to the underlying store.
13 | '''
14 | Sub SaveChanges()
15 | '''
16 | ''' Checks if the unit of work is tracking any new, deleted, or changed entities or relationships that will be sent to the store if SaveChanges() is called.
17 | '''
18 | Function HasChanges() As Boolean
19 | End Interface
20 | '''
21 | ''' Provides the method to create a unit of work of a given type.
22 | '''
23 | ''' A unit of work type.
24 | Public Interface IUnitOfWorkFactory(Of TUnitOfWork As IUnitOfWork)
25 | '''
26 | ''' Creates a new unit of work.
27 | '''
28 | Function CreateUnitOfWork() As TUnitOfWork
29 | Function CreateInstantFeedbackSource(Of TEntity As {Class, New}, TProjection As Class, TPrimaryKey)(ByVal getRepositoryFunc As Func(Of TUnitOfWork, IRepository(Of TEntity, TPrimaryKey)), ByVal projection As Func(Of IRepositoryQuery(Of TEntity), IQueryable(Of TProjection))) As IInstantFeedbackSource(Of TProjection)
30 | End Interface
31 | Public Interface IInstantFeedbackSource(Of TEntity As Class)
32 | Inherits IListSource
33 | Sub Refresh()
34 | Function GetPropertyValue(Of TProperty)(ByVal threadSafeProxy As Object, ByVal propertyExpression As Expression(Of Func(Of TEntity, TProperty))) As TProperty
35 | Function IsLoadedProxy(ByVal threadSafeProxy As Object) As Boolean
36 | End Interface
37 | End Namespace
38 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/DataModel/UnitOfWorkBase.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Collections.Generic
4 | Imports System.Linq.Expressions
5 | Namespace Common.DataModel
6 | '''
7 | ''' The base class for unit of works that provides the storage for repositories.
8 | '''
9 | Public Class UnitOfWorkBase
10 | Private ReadOnly _repositories As Dictionary(Of Type, Object) = New Dictionary(Of Type, Object)()
11 | Protected Function GetRepositoryCore(Of TRepository As IReadOnlyRepository(Of TEntity), TEntity As Class)(ByVal createRepositoryFunc As Func(Of TRepository)) As TRepository
12 | Dim result As Object = Nothing
13 | If Not _repositories.TryGetValue(GetType(TEntity), result) Then
14 | result = createRepositoryFunc()
15 | _repositories(GetType(TEntity)) = result
16 | End If
17 | Return CType(result, TRepository)
18 | End Function
19 | End Class
20 | End Namespace
21 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/Utils/DbExtensions.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections
3 | Imports System.Linq
4 | Namespace Common.Utils
5 | '''
6 | ''' Provides the extension method for implementations of the IQueryable interface.
7 | '''
8 | Public Module DbExtensions
9 | '''
10 | ''' Forces entities to be loaded locally from the IQueryable instance.
11 | '''
12 | ''' An instance of the IQueryable interface from which to load entities.
13 | _
14 | Public Sub Load(ByVal source As IQueryable)
15 | Dim enumerator As IEnumerator = source.GetEnumerator()
16 | While enumerator.MoveNext()
17 | End While
18 | End Sub
19 | End Module
20 | End Namespace
21 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/ViewModel/ISingleObjectViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.ComponentModel.DataAnnotations
3 | Imports System.Linq
4 | Imports System.Linq.Expressions
5 | Imports DevExpress.Mvvm
6 | Imports DevExpress.Mvvm.POCO
7 | Imports DevExpress.Mvvm.DataAnnotations
8 | Imports Common.Utils
9 | Imports Common.DataModel
10 | Namespace Common.ViewModel
11 | '''
12 | ''' The base interface for view models representing a single entity.
13 | '''
14 | ''' An entity type.
15 | ''' An entity primary key type.
16 | Public Interface ISingleObjectViewModel(Of TEntity, TPrimaryKey)
17 | '''
18 | ''' The entity represented by a view model.
19 | '''
20 | ReadOnly Property Entity As TEntity
21 | '''
22 | ''' The entity primary key value.
23 | '''
24 | ReadOnly Property PrimaryKey As TPrimaryKey
25 | End Interface
26 | End Namespace
27 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/ViewModel/LayoutSettings.Designer.vb:
--------------------------------------------------------------------------------
1 | '------------------------------------------------------------------------------
2 | '
3 | ' This code was generated by a tool.
4 | ' Runtime Version:4.0.30319.34209
5 | '
6 | ' Changes to this file may cause incorrect behavior and will be lost if
7 | ' the code is regenerated.
8 | '
9 | '------------------------------------------------------------------------------
10 |
11 | Option Strict On
12 | Option Explicit On
13 |
14 |
15 |
16 | _
18 | Partial Friend NotInheritable Class LayoutSettings
19 | Inherits Global.System.Configuration.ApplicationSettingsBase
20 |
21 | Private Shared defaultInstance As LayoutSettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New LayoutSettings()), LayoutSettings)
22 |
23 | Public Shared ReadOnly Property [Default]() As LayoutSettings
24 | Get
25 | Return defaultInstance
26 | End Get
27 | End Property
28 |
29 | _
32 | Public Property LogicalLayout() As String
33 | Get
34 | Return CType(Me("LogicalLayout"), String)
35 | End Get
36 | Set(value As String)
37 | Me("LogicalLayout") = Value
38 | End Set
39 | End Property
40 |
41 | _
44 | Public Property ViewsLayout() As String
45 | Get
46 | Return CType(Me("ViewsLayout"), String)
47 | End Get
48 | Set(value As String)
49 | Me("ViewsLayout") = Value
50 | End Set
51 | End Property
52 | End Class
53 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/ViewModel/LayoutSettings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/ViewModel/LookUpEntitiesViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.ComponentModel
4 | Imports DevExpress.Mvvm
5 | Imports DevExpress.Mvvm.POCO
6 | Imports System.Collections.ObjectModel
7 | Imports Common.Utils
8 | Imports Common.DataModel
9 | Namespace Common.ViewModel
10 | '''
11 | ''' Represents a POCO view models used by SingleObjectViewModel to exposing collections of related entities.
12 | ''' This is a partial class that provides an extension point to add custom properties, commands and override methods without modifying the auto-generated code.
13 | '''
14 | ''' A repository entity type.
15 | ''' A projection entity type.
16 | ''' A primary key value type.
17 | ''' A unit of work type.
18 | Public Class LookUpEntitiesViewModel(Of TEntity As Class, TProjection As Class, TPrimaryKey, TUnitOfWork As IUnitOfWork)
19 | Inherits EntitiesViewModel(Of TEntity, TProjection, TUnitOfWork)
20 | Implements IDocumentContent
21 | '''
22 | ''' Creates a new instance of LookUpEntitiesViewModel as a POCO view model.
23 | '''
24 | ''' A factory used to create a unit of work instance.
25 | ''' A function that returns a repository representing entities of the given type.
26 | ''' An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type.
27 | Public Shared Function Create(ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of TUnitOfWork), ByVal getRepositoryFunc As Func(Of TUnitOfWork, IReadOnlyRepository(Of TEntity)), Optional ByVal projection As Func(Of IRepositoryQuery(Of TEntity), IQueryable(Of TProjection)) = Nothing) As LookUpEntitiesViewModel(Of TEntity, TProjection, TPrimaryKey, TUnitOfWork)
28 | Return ViewModelSource.Create(Function() New LookUpEntitiesViewModel(Of TEntity, TProjection, TPrimaryKey, TUnitOfWork)(unitOfWorkFactory, getRepositoryFunc, projection))
29 | End Function
30 | '''
31 | ''' Initializes a new instance of the LookUpEntitiesViewModel class.
32 | ''' This constructor is declared protected to avoid an undesired instantiation of the LookUpEntitiesViewModel type without the POCO proxy factory.
33 | '''
34 | ''' A factory used to create a unit of work instance.
35 | ''' A function that returns a repository representing entities of the given type.
36 | ''' A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type.
37 | Protected Sub New(ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of TUnitOfWork), ByVal getRepositoryFunc As Func(Of TUnitOfWork, IReadOnlyRepository(Of TEntity)), ByVal projection As Func(Of IRepositoryQuery(Of TEntity), IQueryable(Of TProjection)))
38 | MyBase.New(unitOfWorkFactory, getRepositoryFunc, projection)
39 | End Sub
40 | Protected Overrides Function CreateEntitiesChangeTracker() As IEntitiesChangeTracker
41 | Return New EntitiesChangeTracker(Of TPrimaryKey)(Me)
42 | End Function
43 | End Class
44 | End Namespace
45 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/ViewModel/Messages.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.ComponentModel
4 | Namespace Common.ViewModel
5 | '''
6 | ''' Represents the type of an entity state change notification that is shown when the IUnitOfWork.SaveChanges method has been called.
7 | '''
8 | Public Enum EntityMessageType
9 | '''
10 | ''' A new entity has been added to the unit of work.
11 | '''
12 | Added
13 | '''
14 | ''' An entity has been removed from the unit of work.
15 | '''
16 | Deleted
17 | '''
18 | ''' One of the entity properties has been modified.
19 | '''
20 | Changed
21 | End Enum
22 | '''
23 | ''' Provides the information about an entity state change notification that is shown when an entity has been added, removed or modified, and the IUnitOfWork.SaveChanges method has been called.
24 | '''
25 | ''' An entity type.
26 | ''' A primary key value type.
27 | Public Class EntityMessage(Of TEntity, TPrimaryKey)
28 | Private _MessageType As EntityMessageType
29 | Private _PrimaryKey As TPrimaryKey
30 | '''
31 | ''' Initializes a new instance of the EntityMessage class.
32 | '''
33 | ''' A primary key of an entity that has been added, removed or modified.
34 | ''' An entity state change notification type.
35 | Public Sub New(ByVal primaryKey As TPrimaryKey, ByVal messageType As EntityMessageType)
36 | Me._PrimaryKey = primaryKey
37 | Me._MessageType = messageType
38 | End Sub
39 | '''
40 | ''' The primary key of entity that has been added, deleted or modified.
41 | '''
42 | Public ReadOnly Property PrimaryKey As TPrimaryKey
43 | Get
44 | Return _PrimaryKey
45 | End Get
46 | End Property
47 | '''
48 | ''' The entity state change notification type.
49 | '''
50 | Public ReadOnly Property MessageType As EntityMessageType
51 | Get
52 | Return _MessageType
53 | End Get
54 | End Property
55 | End Class
56 | '''
57 | ''' A message notifying that all view models should save changes. Usually sent by DocumentsViewModel when the SaveAll command is executed.
58 | '''
59 | Public Class SaveAllMessage
60 | End Class
61 | '''
62 | ''' A message notifying that all view models should close itself. Usually sent by DocumentsViewModel when the CloseAll command is executed.
63 | '''
64 | Public Class CloseAllMessage
65 | Private ReadOnly _cancelEventArgs As CancelEventArgs
66 | '''
67 | ''' Initializes a new instance of the CloseAllMessage class.
68 | '''
69 | ''' An argument of the System.ComponentModel.CancelEventArgs type which can be used to cancel closing.
70 | Public Sub New(ByVal cancelEventArgs As CancelEventArgs)
71 | Me._cancelEventArgs = cancelEventArgs
72 | End Sub
73 | '''
74 | ''' Used to cancel closing and check whether the closing has already been cancelled.
75 | '''
76 | Public Property Cancel As Boolean
77 | Get
78 | Return _cancelEventArgs.Cancel
79 | End Get
80 | Set(value As Boolean)
81 | _cancelEventArgs.Cancel = value
82 | End Set
83 | End Property
84 | End Class
85 | Public Class DestroyOrphanedDocumentsMessage
86 | End Class
87 | '''
88 | ''' Used by the PeekCollectionViewModel to notify that DocumentsViewModel should navigate to the specified module.
89 | '''
90 | ''' The navigation token type.
91 | Public Class NavigateMessage(Of TNavigationToken)
92 | Private _Token As TNavigationToken
93 | '''
94 | ''' Initializes a new instance of the NavigateMessage class.
95 | '''
96 | ''' An object that is used to identify the module to which the DocumentsViewModel should navigate.
97 | Public Sub New(ByVal token As TNavigationToken)
98 | Me._Token = token
99 | End Sub
100 | '''
101 | ''' An object that is used to identify the module to which the DocumentsViewModel should navigate.
102 | '''
103 | Public ReadOnly Property Token As TNavigationToken
104 | Get
105 | Return _Token
106 | End Get
107 | End Property
108 | End Class
109 | End Namespace
110 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/ViewModel/PeekCollectionViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.ComponentModel
3 | Imports System.ComponentModel.DataAnnotations
4 | Imports System.Collections.Generic
5 | Imports System.Linq
6 | Imports System.Linq.Expressions
7 | Imports DevExpress.Mvvm
8 | Imports DevExpress.Mvvm.POCO
9 | Imports DevExpress.Mvvm.DataAnnotations
10 | Imports Common.Utils
11 | Imports Common.DataModel
12 | Namespace Common.ViewModel
13 | '''
14 | ''' A POCO view model exposing a read-only collection of entities of a given type. It is designed for quick navigation between collection views.
15 | ''' This is a partial class that provides an extension point to add custom properties, commands and override methods without modifying the auto-generated code.
16 | '''
17 | ''' A navigation token type.
18 | ''' An entity type.
19 | ''' A primary key value type.
20 | ''' A unit of work type.
21 | Partial Public Class PeekCollectionViewModel(Of TNavigationToken, TEntity As Class, TPrimaryKey, TUnitOfWork As IUnitOfWork)
22 | Inherits CollectionViewModelBase(Of TEntity, TEntity, TPrimaryKey, TUnitOfWork)
23 | '''
24 | ''' Creates a new instance of PeekCollectionViewModel as a POCO view model.
25 | '''
26 | ''' Identifies the module that is the navigation target.
27 | ''' A factory that is used to create a unit of work instance.
28 | ''' A function that returns a repository representing entities of a given type.
29 | ''' An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data.
30 | Public Shared Function Create(ByVal navigationToken As TNavigationToken, ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of TUnitOfWork), ByVal getRepositoryFunc As Func(Of TUnitOfWork, IRepository(Of TEntity, TPrimaryKey)), Optional ByVal projection As Func(Of IRepositoryQuery(Of TEntity), IQueryable(Of TEntity)) = Nothing) As PeekCollectionViewModel(Of TNavigationToken, TEntity, TPrimaryKey, TUnitOfWork)
31 | Return ViewModelSource.Create(Function() New PeekCollectionViewModel(Of TNavigationToken, TEntity, TPrimaryKey, TUnitOfWork)(navigationToken, unitOfWorkFactory, getRepositoryFunc, projection))
32 | End Function
33 | Private _navigationToken As TNavigationToken
34 | Private _pickedEntity As TEntity
35 | '''
36 | ''' Initializes a new instance of the PeekCollectionViewModel class.
37 | ''' This constructor is declared protected to avoid an undesired instantiation of the PeekCollectionViewModel type without the POCO proxy factory.
38 | '''
39 | ''' Identifies the module that is the navigation target.
40 | ''' A factory that is used to create a unit of work instance.
41 | ''' A function that returns a repository representing entities of a given type.
42 | ''' An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data.
43 | Protected Sub New(ByVal navigationToken As TNavigationToken, ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of TUnitOfWork), ByVal getRepositoryFunc As Func(Of TUnitOfWork, IRepository(Of TEntity, TPrimaryKey)), Optional ByVal projection As Func(Of IRepositoryQuery(Of TEntity), IQueryable(Of TEntity)) = Nothing)
44 | MyBase.New(unitOfWorkFactory, getRepositoryFunc, projection, Nothing, Nothing, True)
45 | Me._navigationToken = navigationToken
46 | End Sub
47 | '''
48 | ''' Navigates to the corresponding collection view and selects the given entity.
49 | ''' Since PeekCollectionViewModel is a POCO view model, an instance of this class will also expose the NavigateCommand property that can be used as a binding source in views.
50 | '''
51 | ''' An entity to select within the collection view.
52 | _
53 | Public Sub Navigate(ByVal projectionEntity As TEntity)
54 | _pickedEntity = projectionEntity
55 | SendSelectEntityMessage()
56 | Messenger.[Default].Send(New NavigateMessage(Of TNavigationToken)(_navigationToken), _navigationToken)
57 | End Sub
58 | '''
59 | ''' Determines if a navigation to corresponding collection view can be performed.
60 | ''' Since PeekCollectionViewModel is a POCO view model, this method will be used as a CanExecute callback for NavigateCommand.
61 | '''
62 | ''' An entity to select in the collection view.
63 | Public Function CanNavigate(ByVal projectionEntity As TEntity) As Boolean
64 | Return projectionEntity IsNot Nothing
65 | End Function
66 | Protected Overrides Sub OnInitializeInRuntime()
67 | MyBase.OnInitializeInRuntime()
68 | Messenger.[Default].Register(Of SelectedEntityRequest)(Me, Sub(x) SendSelectEntityMessage())
69 | End Sub
70 | Private Sub SendSelectEntityMessage()
71 | If IsLoaded AndAlso _pickedEntity IsNot Nothing Then
72 | Messenger.[Default].Send(New SelectEntityMessage(CreateRepository().GetProjectionPrimaryKey(_pickedEntity)))
73 | End If
74 | End Sub
75 | End Class
76 | End Namespace
77 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Common/ViewModel/ViewModelLogicalLayoutHelper.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.IO
4 | Imports System.Linq
5 | Imports System.Text
6 | Imports DevExpress.Mvvm
7 | Namespace Common.ViewModel
8 | Public Class ViewModelLogicalLayoutHelper
9 | Public Shared Property PersistentLogicalLayout As String
10 | Get
11 | Return LayoutSettings.[Default].LogicalLayout
12 | End Get
13 | Set(value As String)
14 | LayoutSettings.[Default].LogicalLayout = value
15 | End Set
16 | End Property
17 | Private Shared _persistentViewsLayout As Dictionary(Of String, String)
18 | Public Shared ReadOnly Property PersistentViewsLayout As Dictionary(Of String, String)
19 | Get
20 | If _persistentViewsLayout Is Nothing Then
21 | _persistentViewsLayout = LogicalLayoutSerializationHelper.Deserialize(LayoutSettings.[Default].ViewsLayout)
22 | End If
23 | Return _persistentViewsLayout
24 | End Get
25 | End Property
26 | Public Shared Sub SaveLayout()
27 | LayoutSettings.[Default].ViewsLayout = LogicalLayoutSerializationHelper.Serialize(PersistentViewsLayout)
28 | LayoutSettings.[Default].Save()
29 | End Sub
30 | Public Shared Sub ResetLayout()
31 | PersistentViewsLayout.Clear()
32 | PersistentLogicalLayout = Nothing
33 | SaveLayout()
34 | End Sub
35 | End Class
36 | End Namespace
37 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Data/Expenses.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevExpress-Examples/winforms-mvvm-expenses-app/70a139e6d5909c97e63090201977325d1be58b9a/VB/MVVMExpenses/Data/Expenses.sqlite3
--------------------------------------------------------------------------------
/VB/MVVMExpenses/DataBase/DbContext.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.Linq
4 | Imports System.Text
5 | Imports System.Threading.Tasks
6 | Imports System.Data.Common
7 | Imports System.Data.Entity
8 | Imports System.Data.SQLite
9 | Imports System.IO
10 | Imports DevExpress.Internal
11 | Imports MVVMExpenses.DataModels
12 | Imports System.Data.Entity.Infrastructure
13 | Imports System.Data.SQLite.EF6
14 | Imports System.Data.Entity.Core.Common
15 | Imports System.Reflection
16 |
17 | Namespace MVVMExpenses.DataBase
18 |
19 | Public Class MyDbContext
20 | Inherits System.Data.Entity.DbContext
21 | Shared Sub New()
22 | System.Data.Entity.Database.SetInitializer(Of MyDbContext)(Nothing)
23 | End Sub
24 |
25 | Public Property Accounts() As DbSet(Of Account)
26 | Public Property Categories() As DbSet(Of Category)
27 | Public Property Transactions() As DbSet(Of Transaction)
28 | End Class
29 | End Namespace
--------------------------------------------------------------------------------
/VB/MVVMExpenses/DataBase/MyDbSQLiteConfiguration.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.Data.Common
4 | Imports System.Data.SQLite
5 | Imports System.Data.SQLite.EF6
6 | Imports System.IO
7 | Imports System.Linq
8 | Imports System.Text
9 | Imports System.Threading.Tasks
10 | Imports DevExpress.DocumentServices.ServiceModel.DataContracts.Xpf.Designer
11 | Imports DevExpress.Internal
12 |
13 | Namespace MVVMExpenses.Common.DataModel.EntityFramework
14 | Public Class SQLiteConnectionFactory
15 | Implements System.Data.Entity.Infrastructure.IDbConnectionFactory
16 |
17 | Private Shared filePath As String
18 | Public Function CreateConnection(ByVal nameOrConnectionString As String) As DbConnection Implements System.Data.Entity.Infrastructure.IDbConnectionFactory.CreateConnection
19 | If filePath Is Nothing Then
20 | filePath = DataDirectoryHelper.GetFile("expenses.sqlite3", DataDirectoryHelper.DataFolderName)
21 | File.SetAttributes(filePath, File.GetAttributes(filePath) And (Not FileAttributes.ReadOnly))
22 | End If
23 | Return New SQLiteConnection(New SQLiteConnectionStringBuilder() With {.DataSource = filePath}.ConnectionString)
24 | End Function
25 | End Class
26 |
27 | Public Class MyDbSQLiteConfiguration
28 | Inherits System.Data.Entity.DbConfiguration
29 |
30 | Public Sub New()
31 | SetDefaultConnectionFactory(New SQLiteConnectionFactory())
32 | SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance)
33 | SetProviderFactory("System.Data.SQLite.EF6", System.Data.SQLite.EF6.SQLiteProviderFactory.Instance)
34 | Dim t As Type = Type.GetType("System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6", True, True)
35 | Dim fi As System.Reflection.FieldInfo = t.GetField("Instance", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Static)
36 | SetProviderServices("System.Data.SQLite", DirectCast(fi.GetValue(Nothing), System.Data.Entity.Core.Common.DbProviderServices))
37 | End Sub
38 | End Class
39 | End Namespace
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Models/Account.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.Linq
4 | Imports System.Text
5 | Imports System.Threading.Tasks
6 | Imports System.ComponentModel.DataAnnotations
7 |
8 | Namespace MVVMExpenses.DataModels
9 | Public Class Account
10 |
11 | Public Property ID() As Long
12 |
13 | Public Property Name() As String
14 |
15 | Public Property Amount() As Decimal
16 | Public Overrides Function ToString() As String
17 | Return Name & " (" & Amount.ToString("C") & ")"
18 | End Function
19 | End Class
20 | End Namespace
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Models/Category.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.Linq
4 | Imports System.Text
5 | Imports System.Threading.Tasks
6 | Imports System.ComponentModel.DataAnnotations
7 |
8 | Namespace MVVMExpenses.DataModels
9 | Public Class Category
10 |
11 | Public Property ID() As Long
12 |
13 | Public Property Name() As String
14 |
15 | Public Property Type() As TransactionType
16 | Public Overrides Function ToString() As String
17 | Return Name & " (" & Type.ToString() & ")"
18 | End Function
19 | End Class
20 | End Namespace
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Models/CredentialsSource.vb:
--------------------------------------------------------------------------------
1 | Imports System.Collections.Generic
2 | Imports DevExpress.Mvvm.POCO
3 |
4 | Namespace MVVMExpenses.Models
5 | '
6 | ' TODO - your implementation
7 | Friend NotInheritable Class CredentialsSource
8 |
9 | Private Sub New()
10 | End Sub
11 |
12 | Private Shared credentials As System.Collections.Hashtable
13 | Shared Sub New()
14 | credentials = New System.Collections.Hashtable()
15 | credentials.Add("Guest", GetHash(Nothing))
16 | credentials.Add("John", GetHash("qwerty"))
17 | credentials.Add("Administrator", GetHash("admin"))
18 | credentials.Add("Mary", GetHash("12345"))
19 | End Sub
20 | Friend Shared Function Check(ByVal login As String, ByVal pwd As String) As Boolean
21 | Return Object.Equals(credentials(login), GetHash(pwd))
22 | End Function
23 | Private Shared Function GetHash(ByVal password As String) As Object
24 | Return password
25 | End Function
26 | Friend Shared Iterator Function GetUserNames() As System.Collections.Generic.IEnumerable(Of String)
27 | For Each item As String In credentials.Keys
28 | Yield item
29 | Next item
30 | End Function
31 | End Class
32 | End Namespace
33 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Models/MyDbContextDataModel/IMyDbContextUnitOfWork.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Data
4 | Imports System.Data.Entity
5 | Imports System.Linq.Expressions
6 | Imports System.Collections.Generic
7 | Imports Common.Utils
8 | Imports Common.DataModel
9 | Imports Common.DataModel.EntityFramework
10 | Imports MVVMExpenses.DataBase
11 | Imports MVVMExpenses.DataModels
12 | Namespace MVVMExpenses.Models.MyDbContextDataModel
13 | '''
14 | ''' IMyDbContextUnitOfWork extends the IUnitOfWork interface with repositories representing specific entities.
15 | '''
16 | Public Interface IMyDbContextUnitOfWork
17 | Inherits IUnitOfWork
18 | '''
19 | ''' The Account entities repository.
20 | '''
21 | ReadOnly Property Accounts As IRepository(Of Account, Long)
22 | '''
23 | ''' The Category entities repository.
24 | '''
25 | ReadOnly Property Categories As IRepository(Of Category, Long)
26 | '''
27 | ''' The Transaction entities repository.
28 | '''
29 | ReadOnly Property Transactions As IRepository(Of Transaction, Long)
30 | End Interface
31 | End Namespace
32 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Models/MyDbContextDataModel/MyDbContextUnitOfWork.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Data
4 | Imports System.Data.Entity
5 | Imports System.Linq.Expressions
6 | Imports System.Collections.Generic
7 | Imports Common.Utils
8 | Imports Common.DataModel
9 | Imports Common.DataModel.EntityFramework
10 | Imports MVVMExpenses.DataBase
11 | Imports MVVMExpenses.DataModels
12 | Namespace MVVMExpenses.Models.MyDbContextDataModel
13 | '''
14 | ''' A MyDbContextUnitOfWork instance that represents the run-time implementation of the IMyDbContextUnitOfWork interface.
15 | '''
16 | Public Class MyDbContextUnitOfWork
17 | Inherits DbUnitOfWork(Of MyDbContext)
18 | Implements IMyDbContextUnitOfWork
19 | Public Sub New(ByVal contextFactory As Func(Of MyDbContext))
20 | MyBase.New(contextFactory)
21 | End Sub
22 | Private ReadOnly Property Accounts As IRepository(Of Account, Long) Implements IMyDbContextUnitOfWork.Accounts
23 | Get
24 | Return GetRepository(Function(x) x.[Set](Of Account)(), Function(x) x.ID)
25 | End Get
26 | End Property
27 | Private ReadOnly Property Categories As IRepository(Of Category, Long) Implements IMyDbContextUnitOfWork.Categories
28 | Get
29 | Return GetRepository(Function(x) x.[Set](Of Category)(), Function(x) x.ID)
30 | End Get
31 | End Property
32 | Private ReadOnly Property Transactions As IRepository(Of Transaction, Long) Implements IMyDbContextUnitOfWork.Transactions
33 | Get
34 | Return GetRepository(Function(x) x.[Set](Of Transaction)(), Function(x) x.ID)
35 | End Get
36 | End Property
37 | End Class
38 | End Namespace
39 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Models/MyDbContextDataModel/UnitOfWorkSource.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Data
4 | Imports System.Data.Entity
5 | Imports System.Linq.Expressions
6 | Imports System.Collections.Generic
7 | Imports Common.Utils
8 | Imports Common.DataModel
9 | Imports Common.DataModel.EntityFramework
10 | Imports MVVMExpenses.DataBase
11 | Imports MVVMExpenses.DataModels
12 | Imports DevExpress.Mvvm
13 | Imports System.Collections
14 | Imports System.ComponentModel
15 | Imports DevExpress.Data.Linq
16 | Imports DevExpress.Data.Linq.Helpers
17 | Imports DevExpress.Data.Async.Helpers
18 | Namespace MVVMExpenses.Models.MyDbContextDataModel
19 | '''
20 | ''' Provides methods to obtain the relevant IUnitOfWorkFactory.
21 | '''
22 | Public Module UnitOfWorkSource
23 | '''
24 | ''' Returns the IUnitOfWorkFactory implementation.
25 | '''
26 | Public Function GetUnitOfWorkFactory() As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork)
27 | Return New DbUnitOfWorkFactory(Of IMyDbContextUnitOfWork)(Function() New MyDbContextUnitOfWork(Function() New MyDbContext()))
28 | End Function
29 | End Module
30 | End Namespace
31 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Models/Transaction.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.Linq
4 | Imports System.Text
5 | Imports System.Threading.Tasks
6 | Imports System.ComponentModel.DataAnnotations
7 |
8 | Namespace MVVMExpenses.DataModels
9 | Public Enum TransactionType
10 | Expense
11 | Income
12 | End Enum
13 | Public Class Transaction
14 |
15 | Public Property ID() As Long
16 |
17 | Public Property AccountID() As Long
18 |
19 | Public Overridable Property Account() As Account
20 |
21 | Public Property CategoryID() As Long
22 |
23 | Public Overridable Property Category() As Category
24 |
25 | Public Property [Date]() As Date
26 |
27 | Public Property Amount() As Decimal
28 |
29 | Public Property Comment() As String
30 | End Class
31 | End Namespace
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Models/User.vb:
--------------------------------------------------------------------------------
1 | Namespace MVVMExpenses.DataModels
2 | Public Class User
3 | Public Property Login() As String
4 | Public Property Password() As String
5 | End Class
6 | End Namespace
7 |
8 |
9 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/My Project/AssemblyInfo.vb:
--------------------------------------------------------------------------------
1 | Imports System.Reflection
2 | Imports System.Runtime.CompilerServices
3 | Imports System.Runtime.InteropServices
4 |
5 | ' General Information about an assembly is controlled through the following
6 | ' set of attributes. Change these attribute values to modify the information
7 | ' associated with an assembly.
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ' Setting ComVisible to false makes the types in this assembly not visible
18 | ' to COM components. If you need to access a type in this assembly from
19 | ' COM, set the ComVisible attribute to true on that type.
20 |
21 |
22 | ' The following GUID is for the ID of the typelib if this project is exposed to COM
23 |
24 |
25 | ' Version information for an assembly consists of the following four values:
26 | '
27 | ' Major Version
28 | ' Minor Version
29 | ' Build Number
30 | ' Revision
31 | '
32 | ' You can specify all the values or you can default the Build and Revision Numbers
33 | ' by using the '*' as shown below:
34 | ' [assembly: AssemblyVersion("1.0.*")]
35 |
36 |
37 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/My Project/DataSources/MVVMExpenses.DataModels.Account.datasource:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | MVVMExpenses.DataModels.Account, MVVMExpenses, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
10 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/My Project/DataSources/MVVMExpenses.DataModels.Category.datasource:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | MVVMExpenses.DataModels.Category, MVVMExpenses, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
10 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/My Project/DataSources/MVVMExpenses.DataModels.Transaction.datasource:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | MVVMExpenses.DataModels.Transaction, MVVMExpenses, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
10 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/My Project/Resources.Designer.vb:
--------------------------------------------------------------------------------
1 | '------------------------------------------------------------------------------
2 | '
3 | ' This code was generated by a tool.
4 | ' Runtime Version:4.0.30319.18052
5 | '
6 | ' Changes to this file may cause incorrect behavior and will be lost if
7 | ' the code is regenerated.
8 | '
9 | '------------------------------------------------------------------------------
10 |
11 | Namespace My.Resources
12 |
13 |
14 | '''
15 | ''' A strongly-typed resource class, for looking up localized strings, etc.
16 | '''
17 | ' This class was auto-generated by the StronglyTypedResourceBuilder
18 | ' class via a tool like ResGen or Visual Studio.
19 | ' To add or remove a member, edit your .ResX file then rerun ResGen
20 | ' with the /str option, or rebuild your VS project.
21 |
23 | Friend Module Resources
24 |
25 | Private resourceMan As Global.System.Resources.ResourceManager
26 |
27 | Private resourceCulture As Global.System.Globalization.CultureInfo
28 |
29 | ' internal Resources()
30 | ' {
31 | ' }
32 |
33 | '''
34 | ''' Returns the cached ResourceManager instance used by this class.
35 | '''
36 |
37 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
38 | Get
39 | If (resourceMan Is Nothing) Then
40 | Dim temp As New Global.System.Resources.ResourceManager("Resources", GetType(Resources).Assembly)
41 | resourceMan = temp
42 | End If
43 | Return resourceMan
44 | End Get
45 | End Property
46 |
47 | '''
48 | ''' Overrides the current thread's CurrentUICulture property for all
49 | ''' resource lookups using this strongly typed resource class.
50 | '''
51 |
52 | Friend Property Culture() As Global.System.Globalization.CultureInfo
53 | Get
54 | Return resourceCulture
55 | End Get
56 | Set(ByVal value As System.Globalization.CultureInfo)
57 | resourceCulture = value
58 | End Set
59 | End Property
60 | End Module
61 | End Namespace
62 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/My Project/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/My Project/Settings.Designer.vb:
--------------------------------------------------------------------------------
1 | '------------------------------------------------------------------------------
2 | '
3 | ' This code was generated by a tool.
4 | ' Runtime Version:4.0.30319.18052
5 | '
6 | ' Changes to this file may cause incorrect behavior and will be lost if
7 | ' the code is regenerated.
8 | '
9 | '------------------------------------------------------------------------------
10 |
11 | Namespace My
12 |
13 |
14 |
15 | Friend NotInheritable Partial Class Settings
16 | Inherits System.Configuration.ApplicationSettingsBase
17 |
18 | Private Shared defaultInstance As Settings = (CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New Settings()), Settings))
19 |
20 | Public Shared ReadOnly Property [Default]() As Settings
21 | Get
22 | Return defaultInstance
23 | End Get
24 | End Property
25 | End Class
26 | End Namespace
27 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/My Project/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Program.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.Linq
4 | Imports System.Threading.Tasks
5 | Imports System.Windows.Forms
6 | Imports DevExpress.Skins
7 |
8 | Namespace MVVMExpenses
9 | Friend NotInheritable Class Program
10 |
11 | Private Sub New()
12 | End Sub
13 |
14 | '''
15 | ''' The main entry point for the application.
16 | '''
17 |
18 | Shared Sub Main()
19 | SkinManager.EnableFormSkins()
20 | Application.EnableVisualStyles()
21 | Application.SetCompatibleTextRenderingDefault(False)
22 | Application.Run(New MainView())
23 | End Sub
24 | End Class
25 | End Namespace
26 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/ViewModels/Account/AccountCollectionViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports DevExpress.Mvvm.POCO
4 | Imports Common.Utils
5 | Imports MVVMExpenses.Models.MyDbContextDataModel
6 | Imports Common.DataModel
7 | Imports MVVMExpenses.DataModels
8 | Imports MVVMExpenses.DataBase
9 | Imports Common.ViewModel
10 | Namespace MVVMExpenses.ViewModels
11 | '''
12 | ''' Represents the Accounts collection view model.
13 | '''
14 | Partial Public Class AccountCollectionViewModel
15 | Inherits CollectionViewModel(Of Account, Long, IMyDbContextUnitOfWork)
16 | '''
17 | ''' Creates a new instance of AccountCollectionViewModel as a POCO view model.
18 | '''
19 | ''' A factory used to create a unit of work instance.
20 | Public Shared Function Create(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing) As AccountCollectionViewModel
21 | Return ViewModelSource.Create(Function() New AccountCollectionViewModel(unitOfWorkFactory))
22 | End Function
23 | '''
24 | ''' Initializes a new instance of the AccountCollectionViewModel class.
25 | ''' This constructor is declared protected to avoid undesired instantiation of the AccountCollectionViewModel type without the POCO proxy factory.
26 | '''
27 | ''' A factory used to create a unit of work instance.
28 | Protected Sub New(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing)
29 | MyBase.New(If(unitOfWorkFactory, UnitOfWorkSource.GetUnitOfWorkFactory()), Function(x) x.Accounts)
30 | End Sub
31 | End Class
32 | End Namespace
33 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/ViewModels/Account/AccountViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Linq.Expressions
4 | Imports System.Collections.Generic
5 | Imports System.Collections.ObjectModel
6 | Imports DevExpress.Mvvm
7 | Imports DevExpress.Mvvm.POCO
8 | Imports Common.Utils
9 | Imports MVVMExpenses.Models.MyDbContextDataModel
10 | Imports Common.DataModel
11 | Imports MVVMExpenses.DataModels
12 | Imports MVVMExpenses.DataBase
13 | Imports Common.ViewModel
14 | Namespace MVVMExpenses.ViewModels
15 | '''
16 | ''' Represents the single Account object view model.
17 | '''
18 | Partial Public Class AccountViewModel
19 | Inherits SingleObjectViewModel(Of Account, Long, IMyDbContextUnitOfWork)
20 | '''
21 | ''' Creates a new instance of AccountViewModel as a POCO view model.
22 | '''
23 | ''' A factory used to create a unit of work instance.
24 | Public Shared Function Create(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing) As AccountViewModel
25 | Return ViewModelSource.Create(Function() New AccountViewModel(unitOfWorkFactory))
26 | End Function
27 | '''
28 | ''' Initializes a new instance of the AccountViewModel class.
29 | ''' This constructor is declared protected to avoid undesired instantiation of the AccountViewModel type without the POCO proxy factory.
30 | '''
31 | ''' A factory used to create a unit of work instance.
32 | Protected Sub New(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing)
33 | MyBase.New(If(unitOfWorkFactory, UnitOfWorkSource.GetUnitOfWorkFactory()), Function(x) x.Accounts, Function(x) x.Name)
34 | End Sub
35 |
36 | Public ReadOnly Property AccountTransactionDetails() As CollectionViewModel(Of Transaction, Long, IMyDbContextUnitOfWork)
37 | Get
38 | Return GetDetailsCollectionViewModel(Function(x As AccountViewModel) x.AccountTransactionDetails, Function(x) x.Transactions, Function(x) x.AccountID, Sub(x, key) x.AccountID = key)
39 | End Get
40 | End Property
41 | End Class
42 | End Namespace
43 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/ViewModels/Category/CategoryCollectionViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports DevExpress.Mvvm.POCO
4 | Imports Common.Utils
5 | Imports MVVMExpenses.Models.MyDbContextDataModel
6 | Imports Common.DataModel
7 | Imports MVVMExpenses.DataModels
8 | Imports MVVMExpenses.DataBase
9 | Imports Common.ViewModel
10 | Namespace MVVMExpenses.ViewModels
11 | '''
12 | ''' Represents the Categories collection view model.
13 | '''
14 | Partial Public Class CategoryCollectionViewModel
15 | Inherits CollectionViewModel(Of Category, Long, IMyDbContextUnitOfWork)
16 | '''
17 | ''' Creates a new instance of CategoryCollectionViewModel as a POCO view model.
18 | '''
19 | ''' A factory used to create a unit of work instance.
20 | Public Shared Function Create(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing) As CategoryCollectionViewModel
21 | Return ViewModelSource.Create(Function() New CategoryCollectionViewModel(unitOfWorkFactory))
22 | End Function
23 | '''
24 | ''' Initializes a new instance of the CategoryCollectionViewModel class.
25 | ''' This constructor is declared protected to avoid undesired instantiation of the CategoryCollectionViewModel type without the POCO proxy factory.
26 | '''
27 | ''' A factory used to create a unit of work instance.
28 | Protected Sub New(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing)
29 | MyBase.New(If(unitOfWorkFactory, UnitOfWorkSource.GetUnitOfWorkFactory()), Function(x) x.Categories)
30 | End Sub
31 | End Class
32 | End Namespace
33 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/ViewModels/Category/CategoryViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Linq.Expressions
4 | Imports System.Collections.Generic
5 | Imports System.Collections.ObjectModel
6 | Imports DevExpress.Mvvm
7 | Imports DevExpress.Mvvm.POCO
8 | Imports Common.Utils
9 | Imports MVVMExpenses.Models.MyDbContextDataModel
10 | Imports Common.DataModel
11 | Imports MVVMExpenses.DataModels
12 | Imports MVVMExpenses.DataBase
13 | Imports Common.ViewModel
14 | Namespace MVVMExpenses.ViewModels
15 | '''
16 | ''' Represents the single Category object view model.
17 | '''
18 | Partial Public Class CategoryViewModel
19 | Inherits SingleObjectViewModel(Of Category, Long, IMyDbContextUnitOfWork)
20 | '''
21 | ''' Creates a new instance of CategoryViewModel as a POCO view model.
22 | '''
23 | ''' A factory used to create a unit of work instance.
24 | Public Shared Function Create(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing) As CategoryViewModel
25 | Return ViewModelSource.Create(Function() New CategoryViewModel(unitOfWorkFactory))
26 | End Function
27 | '''
28 | ''' Initializes a new instance of the CategoryViewModel class.
29 | ''' This constructor is declared protected to avoid undesired instantiation of the CategoryViewModel type without the POCO proxy factory.
30 | '''
31 | ''' A factory used to create a unit of work instance.
32 | Protected Sub New(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing)
33 | MyBase.New(If(unitOfWorkFactory, UnitOfWorkSource.GetUnitOfWorkFactory()), Function(x) x.Categories, Function(x) x.Name)
34 | End Sub
35 |
36 | Public ReadOnly Property CategoryTransactionDetails() As CollectionViewModel(Of Transaction, Long, IMyDbContextUnitOfWork)
37 | Get
38 | Return GetDetailsCollectionViewModel(Function(x As CategoryViewModel) x.CategoryTransactionDetails, Function(x) x.Transactions, Function(x) x.CategoryID, Sub(x, key) x.CategoryID = key)
39 | End Get
40 | End Property
41 | End Class
42 | End Namespace
43 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/ViewModels/LoginViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports MVVMExpenses.Models
2 | Imports DevExpress.Mvvm.POCO
3 |
4 | Namespace MVVMExpenses.ViewModels
5 | Public Class LoginViewModel
6 | Public ReadOnly Property LookUpUsers() As IEnumerable(Of String)
7 | Get
8 | Return CredentialsSource.GetUserNames()
9 | End Get
10 | End Property
11 |
12 | Public Overridable Property CurrentUser() As MVVMExpenses.DataModels.User
13 | Private privateIsCurrentUserCredentialsValid As Boolean
14 |
15 | Public Property IsCurrentUserCredentialsValid() As Boolean
16 | Get
17 | Return privateIsCurrentUserCredentialsValid
18 | End Get
19 | Private Set(ByVal value As Boolean)
20 | privateIsCurrentUserCredentialsValid = value
21 | End Set
22 | End Property
23 |
24 |
25 | Public Sub Init()
26 | Me.CurrentUser = New MVVMExpenses.DataModels.User()
27 | End Sub
28 |
29 | Public Sub Update()
30 | IsCurrentUserCredentialsValid = CredentialsSource.Check(CurrentUser.Login, CurrentUser.Password)
31 | End Sub
32 |
33 | Public Shared Function Create() As LoginViewModel
34 | Return ViewModelSource.Create(Of LoginViewModel)()
35 | End Function
36 | End Class
37 | End Namespace
38 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/ViewModels/MyDbContextViewModel.partial.vb:
--------------------------------------------------------------------------------
1 | Imports System.ComponentModel
2 | Imports System.Windows
3 | Imports DevExpress.Mvvm
4 | Imports DevExpress.Mvvm.POCO
5 | Imports DevExpress.Utils.MVVM
6 | Imports MVVMExpenses.Models.MyDbContextDataModel
7 | Imports MVVMExpenses.ViewModels
8 | Imports Common.ViewModel
9 |
10 | Namespace MVVMExpenses.ViewModels
11 | Partial Public Class MyDbContextViewModel
12 | Private loginViewModel As LoginViewModel
13 |
14 | Protected Sub New()
15 | MyBase.New(UnitOfWorkSource.GetUnitOfWorkFactory())
16 | loginViewModel = loginViewModel.Create()
17 | loginViewModel.SetParentViewModel(Me)
18 | End Sub
19 | Protected ReadOnly Property DialogService() As IDialogService
20 | Get
21 | Return Me.GetService(Of IDialogService)()
22 | End Get
23 | End Property
24 | Protected ReadOnly Property MessageService() As IMessageBoxService
25 | Get
26 | Return Me.GetService(Of IMessageBoxService)()
27 | End Get
28 | End Property
29 |
30 | Public Overrides Sub OnLoaded(ByVal [module] As MyDbContextModuleDescription)
31 | MyBase.OnLoaded([module])
32 | Login()
33 | End Sub
34 | Public Overrides Sub OnClosing(ByVal cancelEventArgs As CancelEventArgs)
35 | MyBase.OnClosing(cancelEventArgs)
36 | If Not cancelEventArgs.Cancel Then
37 | If State = AppState.Authorized AndAlso MessageService.ShowMessage("Do you really want to close the application?", "Confirm", MessageButton.YesNo) = MessageResult.No Then
38 | cancelEventArgs.Cancel = True
39 | End If
40 | End If
41 | End Sub
42 | '
43 | Public Overridable Property State() As AppState
44 | ' Shows the Login View
45 | Public Sub Login()
46 | OnLogin(DialogService.ShowDialog(MessageButton.OKCancel, "Please enter you credentials", "LoginView", loginViewModel))
47 | End Sub
48 | Public Sub Logout()
49 | State = AppState.ExitQueued
50 | System.Diagnostics.Process.Start(System.Windows.Forms.Application.ExecutablePath)
51 | End Sub
52 | Public Function CanLogout() As Boolean
53 | Return State = AppState.Authorized
54 | End Function
55 | 'Occurs whenever the end-user clicks a dialog button
56 | Private Sub OnLogin(ByVal result As MessageResult)
57 | If result = MessageResult.Cancel Then
58 | State = AppState.ExitQueued
59 | Else
60 | If loginViewModel.IsCurrentUserCredentialsValid Then
61 | State = AppState.Authorized
62 | Else
63 | Login()
64 | End If
65 | End If
66 | End Sub
67 | Protected Sub OnStateChanged()
68 | Me.RaiseCanExecuteChanged(Sub(x) x.Logout())
69 | If State = AppState.Authorized Then
70 | Messenger.Default.Send(Of String)(loginViewModel.CurrentUser.Login)
71 | Else
72 | Messenger.Default.Send(Of String)(String.Empty)
73 | End If
74 | End Sub
75 | End Class
76 |
77 | Public Enum AppState
78 | NotAuthorized
79 | Authorized
80 | ExitQueued
81 | End Enum
82 | End Namespace
--------------------------------------------------------------------------------
/VB/MVVMExpenses/ViewModels/MyDbContextViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.Linq
4 | Imports System.ComponentModel
5 | Imports DevExpress.Mvvm
6 | Imports DevExpress.Mvvm.POCO
7 | Imports Common.DataModel
8 | Imports Common.ViewModel
9 | Imports MVVMExpenses.Models.MyDbContextDataModel
10 | Imports MVVMExpenses.DataBase
11 | Imports MVVMExpenses.DataModels
12 | Namespace MVVMExpenses.ViewModels
13 | '''
14 | ''' Represents the root POCO view model for the MyDbContext data model.
15 | '''
16 | Partial Public Class MyDbContextViewModel
17 | Inherits DocumentsViewModel(Of MyDbContextModuleDescription, IMyDbContextUnitOfWork)
18 | Private Const _TablesGroup As String = "Tables"
19 | Private Const _ViewsGroup As String = "Views"
20 | '''
21 | ''' Creates a new instance of MyDbContextViewModel as a POCO view model.
22 | '''
23 | Public Shared Function Create() As MyDbContextViewModel
24 | Return ViewModelSource.Create(Function() New MyDbContextViewModel())
25 | End Function
26 | '''
27 | ''' Initializes a new instance of the MyDbContextViewModel class.
28 | ''' This constructor is declared protected to avoid undesired instantiation of the MyDbContextViewModel type without the POCO proxy factory.
29 | '''
30 | 'Protected Sub New()
31 | ' MyBase.New(UnitOfWorkSource.GetUnitOfWorkFactory())
32 | 'End Sub
33 | Protected Overrides Function CreateModules() As MyDbContextModuleDescription()
34 | Return New MyDbContextModuleDescription() {New MyDbContextModuleDescription("Accounts", "AccountCollectionView", _TablesGroup, GetPeekCollectionViewModelFactory(Function(x) x.Accounts)), New MyDbContextModuleDescription("Categories", "CategoryCollectionView", _TablesGroup, GetPeekCollectionViewModelFactory(Function(x) x.Categories)), New MyDbContextModuleDescription("Transactions", "TransactionCollectionView", _TablesGroup, GetPeekCollectionViewModelFactory(Function(x) x.Transactions))}
35 | End Function
36 | End Class
37 | Partial Public Class MyDbContextModuleDescription
38 | Inherits ModuleDescription(Of MyDbContextModuleDescription)
39 | Public Sub New(ByVal title As String, ByVal documentType As String, ByVal group As String, Optional ByVal peekCollectionViewModelFactory As Func(Of MyDbContextModuleDescription, Object) = Nothing)
40 | MyBase.New(title, documentType, group, peekCollectionViewModelFactory)
41 | End Sub
42 | End Class
43 | End Namespace
44 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/ViewModels/Transaction/TransactionCollectionViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports DevExpress.Mvvm.POCO
4 | Imports Common.Utils
5 | Imports MVVMExpenses.Models.MyDbContextDataModel
6 | Imports Common.DataModel
7 | Imports MVVMExpenses.DataModels
8 | Imports MVVMExpenses.DataBase
9 | Imports Common.ViewModel
10 | Namespace MVVMExpenses.ViewModels
11 | '''
12 | ''' Represents the Transactions collection view model.
13 | '''
14 | Partial Public Class TransactionCollectionViewModel
15 | Inherits CollectionViewModel(Of Transaction, Long, IMyDbContextUnitOfWork)
16 | '''
17 | ''' Creates a new instance of TransactionCollectionViewModel as a POCO view model.
18 | '''
19 | ''' A factory used to create a unit of work instance.
20 | Public Shared Function Create(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing) As TransactionCollectionViewModel
21 | Return ViewModelSource.Create(Function() New TransactionCollectionViewModel(unitOfWorkFactory))
22 | End Function
23 | '''
24 | ''' Initializes a new instance of the TransactionCollectionViewModel class.
25 | ''' This constructor is declared protected to avoid undesired instantiation of the TransactionCollectionViewModel type without the POCO proxy factory.
26 | '''
27 | ''' A factory used to create a unit of work instance.
28 | Protected Sub New(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing)
29 | MyBase.New(If(unitOfWorkFactory, UnitOfWorkSource.GetUnitOfWorkFactory()), Function(x) x.Transactions)
30 | End Sub
31 | End Class
32 | End Namespace
33 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/ViewModels/Transaction/TransactionViewModel.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Linq
3 | Imports System.Linq.Expressions
4 | Imports System.Collections.Generic
5 | Imports System.Collections.ObjectModel
6 | Imports DevExpress.Mvvm
7 | Imports DevExpress.Mvvm.POCO
8 | Imports Common.Utils
9 | Imports MVVMExpenses.Models.MyDbContextDataModel
10 | Imports Common.DataModel
11 | Imports MVVMExpenses.DataModels
12 | Imports MVVMExpenses.DataBase
13 | Imports Common.ViewModel
14 | Namespace MVVMExpenses.ViewModels
15 | '''
16 | ''' Represents the single Transaction object view model.
17 | '''
18 | Partial Public Class TransactionViewModel
19 | Inherits SingleObjectViewModel(Of Transaction, Long, IMyDbContextUnitOfWork)
20 | '''
21 | ''' Creates a new instance of TransactionViewModel as a POCO view model.
22 | '''
23 | ''' A factory used to create a unit of work instance.
24 | Public Shared Function Create(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing) As TransactionViewModel
25 | Return ViewModelSource.Create(Function() New TransactionViewModel(unitOfWorkFactory))
26 | End Function
27 | '''
28 | ''' Initializes a new instance of the TransactionViewModel class.
29 | ''' This constructor is declared protected to avoid undesired instantiation of the TransactionViewModel type without the POCO proxy factory.
30 | '''
31 | ''' A factory used to create a unit of work instance.
32 | Protected Sub New(Optional ByVal unitOfWorkFactory As IUnitOfWorkFactory(Of IMyDbContextUnitOfWork) = Nothing)
33 | MyBase.New(If(unitOfWorkFactory, UnitOfWorkSource.GetUnitOfWorkFactory()), Function(x) x.Transactions, Function(x) x.Comment)
34 | End Sub
35 | '''
36 | ''' The view model that contains a look-up collection of Accounts for the corresponding navigation property in the view.
37 | '''
38 | Public ReadOnly Property LookUpAccounts As IEntitiesViewModel(Of Account)
39 | Get
40 | Return GetLookUpEntitiesViewModel(Function(x As TransactionViewModel) x.LookUpAccounts, Function(x) x.Accounts)
41 | End Get
42 | End Property
43 | '''
44 | ''' The view model that contains a look-up collection of Categories for the corresponding navigation property in the view.
45 | '''
46 | Public ReadOnly Property LookUpCategories As IEntitiesViewModel(Of Category)
47 | Get
48 | Return GetLookUpEntitiesViewModel(Function(x As TransactionViewModel) x.LookUpCategories, Function(x) x.Categories)
49 | End Get
50 | End Property
51 | End Class
52 | End Namespace
53 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Views/Account/AccountsEditFormView.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.ComponentModel
4 | Imports System.Drawing
5 | Imports System.Data
6 | Imports System.Text
7 | Imports System.Linq
8 | Imports System.Threading.Tasks
9 | Imports System.Windows.Forms
10 | Imports DevExpress.XtraEditors
11 | Imports MVVMExpenses.ViewModels
12 | Imports DevExpress.XtraGrid.Views
13 |
14 | Namespace MVVMExpenses.Common.Views.Account
15 |
16 | Partial Public Class AccountsEditFormView
17 | Inherits DevExpress.XtraEditors.XtraUserControl
18 |
19 | Public Sub New()
20 | InitializeComponent()
21 | If Not DesignMode Then
22 | InitBindings()
23 | End If
24 | End Sub
25 |
26 | Private Sub InitBindings()
27 | Dim fluent = mvvmContext1.OfType(Of AccountViewModel)()
28 | fluent.SetObjectDataSourceBinding(accountBindingSource, Function(x) x.Entity, Sub(x) x.Update())
29 | fluent.SetBinding(GridControl1, Function(gc) gc.DataSource, Function(x) x.AccountTransactionDetails.Entities)
30 | CType(GridControl1.MainView, DevExpress.XtraGrid.Views.Grid.GridView).Columns("Account").Visible = False
31 | End Sub
32 |
33 |
34 | End Class
35 | End Namespace
36 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Views/Account/AccountsView.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.ComponentModel
4 | Imports System.Drawing
5 | Imports System.Data
6 | Imports System.Text
7 | Imports System.Linq
8 | Imports System.Threading.Tasks
9 | Imports System.Windows.Forms
10 | Imports DevExpress.XtraEditors
11 | Imports MVVMExpenses.ViewModels
12 | Imports DevExpress.Utils.MVVM.Services
13 |
14 | Namespace MVVMExpenses.Common.Views.Account
15 |
16 | Partial Public Class AccountsView
17 | Inherits DevExpress.XtraEditors.XtraUserControl
18 |
19 | Public Sub New()
20 | InitializeComponent()
21 | If Not DesignMode Then
22 | InitBindings()
23 | End If
24 | gridView1.OptionsBehavior.Editable = False
25 | gridView1.OptionsSelection.MultiSelect = True
26 | gridView1.OptionsSelection.MultiSelectMode = DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode.RowSelect
27 | End Sub
28 |
29 | Private Sub InitBindings()
30 | Dim fluentAPI = mvvmContext1.OfType(Of AccountCollectionViewModel)()
31 | fluentAPI.SetBinding(gridView1, Function(gView) gView.LoadingPanelVisible, Function(x) x.IsLoading)
32 | fluentAPI.SetBinding(gridControl1, Function(gControl) gControl.DataSource, Function(x) x.Entities)
33 |
34 | fluentAPI.WithEvent(Of DevExpress.XtraGrid.Views.Base.ColumnView, DevExpress.XtraGrid.Views.Base.FocusedRowObjectChangedEventArgs)(gridView1, "FocusedRowObjectChanged").SetBinding(Function(x) x.SelectedEntity, Function(args) TryCast(args.Row, DataModels.Account), Sub(gView, entity) gView.FocusedRowHandle = gView.FindRow(entity))
35 | fluentAPI.WithEvent(Of DevExpress.XtraGrid.Views.Grid.RowCellClickEventArgs)(gridView1, "RowCellClick").EventToCommand(Sub(x) x.Edit(Nothing), Function(x) x.SelectedEntity, Function(args) (args.Clicks = 2) AndAlso (args.Button = MouseButtons.Left))
36 |
37 | fluentAPI.WithEvent(Of DevExpress.Data.SelectionChangedEventArgs)(gridView1, "SelectionChanged").SetBinding(Function(x) x.Selection, Function(e) GetSelectedAccounts())
38 | End Sub
39 |
40 | Private Function GetSelectedAccounts() As IEnumerable(Of MVVMExpenses.DataModels.Account)
41 | Return gridView1.GetSelectedRows().Select(Function(r) TryCast(gridView1.GetRow(r), MVVMExpenses.DataModels.Account))
42 | End Function
43 |
44 | Private Sub BarButtonItem8_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs)
45 |
46 | End Sub
47 |
48 | Private Sub BarButtonItem7_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs)
49 | End Sub
50 | End Class
51 | End Namespace
52 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Views/Category/CategoriesEditFormView.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.ComponentModel
4 | Imports System.Drawing
5 | Imports System.Data
6 | Imports System.Text
7 | Imports System.Linq
8 | Imports System.Threading.Tasks
9 | Imports System.Windows.Forms
10 | Imports DevExpress.XtraEditors
11 | Imports MVVMExpenses.ViewModels
12 |
13 |
14 | Namespace MVVMExpenses.Common.Views.Category
15 |
16 | Partial Public Class CategoriesEditFormView
17 | Inherits DevExpress.XtraEditors.XtraUserControl
18 |
19 | Public Sub New()
20 | InitializeComponent()
21 | Me.TypeImageComboBoxEdit.Properties.Items.AddEnum(Of DataModels.TransactionType)()
22 | If Not DesignMode Then
23 | InitBindings()
24 | End If
25 | End Sub
26 |
27 | Private Sub InitBindings()
28 | Dim fluent = mvvmContext1.OfType(Of CategoryViewModel)()
29 | fluent.SetObjectDataSourceBinding(categoryBindingSource, Function(x) x.Entity, Sub(x) x.Update())
30 | fluent.SetBinding(GridControl1, Function(gc) gc.DataSource, Function(x) x.CategoryTransactionDetails.Entities)
31 | CType(GridControl1.MainView, DevExpress.XtraGrid.Views.Grid.GridView).Columns("Category").Visible = False
32 | End Sub
33 | End Class
34 | End Namespace
35 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Views/Category/CategoriesView.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.ComponentModel
4 | Imports System.Drawing
5 | Imports System.Data
6 | Imports System.Text
7 | Imports System.Linq
8 | Imports System.Threading.Tasks
9 | Imports System.Windows.Forms
10 | Imports DevExpress.XtraEditors
11 | Imports DevExpress.Utils.MVVM.Services
12 | Imports MVVMExpenses.ViewModels
13 |
14 | Namespace MVVMExpenses.Common.Views.Category
15 |
16 | Partial Public Class CategoriesView
17 | Inherits DevExpress.XtraEditors.XtraUserControl
18 |
19 | Public Sub New()
20 | InitializeComponent()
21 | If Not DesignMode Then
22 | InitBindings()
23 | End If
24 | gridView1.OptionsBehavior.Editable = False
25 | gridView1.OptionsSelection.MultiSelect = True
26 | gridView1.OptionsSelection.MultiSelectMode = DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode.RowSelect
27 | End Sub
28 |
29 | Private Sub InitBindings()
30 | Dim fluent = mvvmContext1.OfType(Of CategoryCollectionViewModel)()
31 | Dim fluentAPI = mvvmContext1.OfType(Of CategoryCollectionViewModel)()
32 | fluentAPI.SetBinding(gridView1, Function(gView) gView.LoadingPanelVisible, Function(x) x.IsLoading)
33 | fluentAPI.SetBinding(gridControl1, Function(gControl) gControl.DataSource, Function(x) x.Entities)
34 |
35 | fluentAPI.WithEvent(Of DevExpress.XtraGrid.Views.Base.ColumnView, DevExpress.XtraGrid.Views.Base.FocusedRowObjectChangedEventArgs)(gridView1, "FocusedRowObjectChanged").SetBinding(Function(x) x.SelectedEntity, Function(args) TryCast(args.Row, DataModels.Category), Sub(gView, entity) gView.FocusedRowHandle = gView.FindRow(entity))
36 | fluentAPI.WithEvent(Of DevExpress.XtraGrid.Views.Grid.RowCellClickEventArgs)(gridView1, "RowCellClick").EventToCommand(Sub(x) x.Edit(Nothing), Function(x) x.SelectedEntity, Function(args) (args.Clicks = 2) AndAlso (args.Button = MouseButtons.Left))
37 |
38 | fluentAPI.WithEvent(Of DevExpress.Data.SelectionChangedEventArgs)(gridView1, "SelectionChanged").SetBinding(Function(x) x.Selection, Function(e) GetSelectedCategories())
39 | End Sub
40 |
41 | Private Function GetSelectedCategories() As IEnumerable(Of MVVMExpenses.DataModels.Category)
42 | Return gridView1.GetSelectedRows().Select(Function(r) TryCast(gridView1.GetRow(r), MVVMExpenses.DataModels.Category))
43 | End Function
44 | End Class
45 | End Namespace
46 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Views/LoginView.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.ComponentModel
4 | Imports System.Drawing
5 | Imports System.Data
6 | Imports System.Text
7 | Imports System.Linq
8 | Imports System.Threading.Tasks
9 | Imports System.Windows.Forms
10 | Imports DevExpress.XtraEditors
11 | Imports MVVMExpenses.ViewModels
12 | Imports DevExpress.Utils.MVVM.Services
13 |
14 | Namespace MVVMExpenses.Common.Views
15 | Partial Public Class LoginView
16 | Inherits DevExpress.XtraEditors.XtraUserControl
17 |
18 | Public Sub New()
19 | InitializeComponent()
20 | PasswordTextEdit.Properties.PasswordChar = "*"c
21 | End Sub
22 |
23 | Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
24 | MyBase.OnLoad(e)
25 | Dim fluentAPI = mvvmContext1.OfType(Of LoginViewModel)()
26 | fluentAPI.SetObjectDataSourceBinding(UserBindingSource, Function(x) x.CurrentUser, Sub(x) x.Update())
27 |
28 |
29 | For Each item As String In mvvmContext1.GetViewModel(Of LoginViewModel)().LookUpUsers
30 | LoginTextEdit.Properties.Items.Add(item)
31 | Next item
32 | fluentAPI.ViewModel.Init()
33 | End Sub
34 |
35 | End Class
36 | End Namespace
37 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Views/MainView.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.ComponentModel
3 | Imports System.Windows.Forms
4 | Imports DevExpress.Mvvm
5 | Imports DevExpress.XtraEditors
6 | Imports MVVMExpenses.ViewModels
7 |
8 | Namespace MVVMExpenses
9 | Partial Public Class MainView
10 | Inherits XtraForm
11 |
12 | Public Sub New()
13 | InitializeComponent()
14 | Me.Opacity = 0
15 | If Not DesignMode Then
16 | InitializeNavigation()
17 | End If
18 | AddHandler ribbonControl1.Merge, AddressOf ribbonControl1_Merge
19 | End Sub
20 | Private Sub ribbonControl1_Merge(ByVal sender As Object, ByVal e As DevExpress.XtraBars.Ribbon.RibbonMergeEventArgs)
21 | ribbonControl1.SelectedPage = e.MergedChild.SelectedPage
22 | End Sub
23 | Private Sub InitializeNavigation()
24 | Dim fluentAPI = mvvmContext1.OfType(Of MyDbContextViewModel)()
25 | fluentAPI.BindCommand(biAccounts, Sub(x, m) x.Show(m), Function(x) x.Modules(0))
26 | fluentAPI.BindCommand(biCategories, Sub(x, m) x.Show(m), Function(x) x.Modules(1))
27 | fluentAPI.BindCommand(biTransactions, Sub(x, m) x.Show(m), Function(x) x.Modules(2))
28 | '
29 | fluentAPI.BindCommand(biLogout, Sub(x) x.Logout())
30 | '
31 | fluentAPI.WithEvent(Me, "Load").EventToCommand(Sub(x) x.OnLoaded(Nothing), Function(x) x.DefaultModule)
32 | fluentAPI.WithEvent(Of FormClosingEventArgs)(Me, "FormClosing").EventToCommand(Sub(x) x.OnClosing(Nothing), New Func(Of CancelEventArgs, Object)(Function(args) args))
33 | fluentAPI.SetTrigger(Function(x) x.State, Sub(state)
34 | If state = AppState.Authorized Then
35 | Opacity = 1
36 | End If
37 | If state = AppState.ExitQueued Then
38 | Close()
39 | End If
40 | End Sub)
41 | Messenger.Default.Register(Of String)(Me, AddressOf OnUserNameMessage)
42 | End Sub
43 | Public Sub OnUserNameMessage(ByVal userName As String)
44 | If String.IsNullOrEmpty(userName) Then
45 | Me.Text = "Expenses Application"
46 | Else
47 | Me.Text = "Expenses Application - (" & userName & ")"
48 | End If
49 | End Sub
50 | End Class
51 | End Namespace
52 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Views/Transaction/TransactionsEditFormView.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.ComponentModel
4 | Imports System.Drawing
5 | Imports System.Data
6 | Imports System.Text
7 | Imports System.Linq
8 | Imports System.Threading.Tasks
9 | Imports System.Windows.Forms
10 | Imports DevExpress.XtraEditors
11 | Imports MVVMExpenses.ViewModels
12 |
13 | Namespace MVVMExpenses.Common.Views.Transaction
14 |
15 | Partial Public Class TransactionsEditFormView
16 | Inherits DevExpress.XtraEditors.XtraUserControl
17 |
18 | Public Sub New()
19 | InitializeComponent()
20 | If Not DesignMode Then
21 | InitBindings()
22 | End If
23 | End Sub
24 |
25 | Private Sub InitBindings()
26 | Dim fluent = mvvmContext1.OfType(Of TransactionViewModel)()
27 | fluent.SetObjectDataSourceBinding(bindingSource, Function(x) x.Entity, Sub(x) x.Update())
28 | fluent.SetBinding(accountBindingSource, Function(abs) abs.DataSource, Function(x) x.LookUpAccounts.Entities)
29 | fluent.SetBinding(categoryBindingSource, Function(cbs) cbs.DataSource, Function(x) x.LookUpCategories.Entities)
30 | End Sub
31 | End Class
32 | End Namespace
33 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/Views/Transaction/TransactionsView.vb:
--------------------------------------------------------------------------------
1 | Imports System
2 | Imports System.Collections.Generic
3 | Imports System.ComponentModel
4 | Imports System.Drawing
5 | Imports System.Data
6 | Imports System.Text
7 | Imports System.Linq
8 | Imports System.Threading.Tasks
9 | Imports System.Windows.Forms
10 | Imports DevExpress.XtraEditors
11 | Imports DevExpress.XtraGrid.Views.Base
12 | Imports DevExpress.XtraGrid.Views.Grid
13 | Imports MVVMExpenses.ViewModels
14 |
15 | Namespace MVVMExpenses.Common.Views.Transaction
16 |
17 | Partial Public Class TransactionsView
18 | Inherits DevExpress.XtraEditors.XtraUserControl
19 |
20 | Public Sub New()
21 | InitializeComponent()
22 | If Not DesignMode Then
23 | InitBindings()
24 | End If
25 | gridView1.OptionsBehavior.Editable = False
26 | gridView1.OptionsSelection.MultiSelect = True
27 | gridView1.OptionsSelection.MultiSelectMode = DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode.RowSelect
28 | End Sub
29 |
30 | Private Sub InitBindings()
31 | Dim fluentAPI = mvvmContext1.OfType(Of TransactionCollectionViewModel)()
32 | fluentAPI.SetBinding(gridView1, Function(gView) gView.LoadingPanelVisible, Function(x) x.IsLoading)
33 | fluentAPI.SetBinding(gridControl1, Function(gControl) gControl.DataSource, Function(x) x.Entities)
34 |
35 | fluentAPI.WithEvent(Of ColumnView, FocusedRowObjectChangedEventArgs)(gridView1, "FocusedRowObjectChanged").SetBinding(Function(x) x.SelectedEntity, Function(args) TryCast(args.Row, DataModels.Transaction), Sub(gView, entity) gView.FocusedRowHandle = gView.FindRow(entity))
36 | fluentAPI.WithEvent(Of RowCellClickEventArgs)(gridView1, "RowCellClick").EventToCommand(Sub(x) x.Edit(Nothing), Function(x) x.SelectedEntity, Function(args) (args.Clicks = 2) AndAlso (args.Button = MouseButtons.Left))
37 | fluentAPI.WithEvent(Of DevExpress.Data.SelectionChangedEventArgs)(gridView1, "SelectionChanged").SetBinding(Function(x) x.Selection, Function(e) GetSelectedCategories())
38 | End Sub
39 |
40 | Private Function GetSelectedCategories() As IEnumerable(Of MVVMExpenses.DataModels.Transaction)
41 | Return gridView1.GetSelectedRows().Select(Function(r) TryCast(gridView1.GetRow(r), MVVMExpenses.DataModels.Transaction))
42 | End Function
43 | End Class
44 | End Namespace
45 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/VB/MVVMExpenses/sqlite/System.Data.SQLite.EF6.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevExpress-Examples/winforms-mvvm-expenses-app/70a139e6d5909c97e63090201977325d1be58b9a/VB/MVVMExpenses/sqlite/System.Data.SQLite.EF6.dll
--------------------------------------------------------------------------------
/VB/MVVMExpenses/sqlite/System.Data.SQLite.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevExpress-Examples/winforms-mvvm-expenses-app/70a139e6d5909c97e63090201977325d1be58b9a/VB/MVVMExpenses/sqlite/System.Data.SQLite.dll
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "runOnWeb": false,
3 | "autoGenerateVb": false
4 | }
--------------------------------------------------------------------------------