├── Libs └── MvvmHelpers-4.04 │ ├── Julmar.Core.dll │ ├── JulMar.Wpf.Helpers.dll │ ├── Julmar.Wpf.Behaviors.dll │ └── Julmar.Wpf.Behaviors.XML ├── WPFSimpleDemo ├── Constants │ └── Messages.cs ├── Messages │ └── EditMessage.cs ├── Entities │ ├── User.cs │ └── BaseEntity.cs ├── Persistance │ ├── CustomType │ │ ├── IStringCipher.cs │ │ ├── EncryptedString.cs │ │ └── DefaultStringCipher.cs │ └── NhMapping │ │ └── UserClassMap.cs ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Validation │ ├── IPasswordRule.cs │ ├── PasswordRuleAttribute.cs │ └── DefaultPasswordRule.cs ├── App.xaml.cs ├── MyServiceLocatorProvider.cs ├── MainWindow.xaml.cs ├── packages.config ├── App.config ├── App.xaml ├── Model │ ├── UserModel.cs │ └── BaseModel.cs ├── Bootstrapper.cs ├── MainWindow.xaml ├── Helpers │ └── BindingListSortable.cs ├── Behaviors │ └── PasswordBoxHelper.cs ├── MainViewModel.cs ├── CustomControls │ ├── TooolBarCadastro.xaml.cs │ └── TooolBarCadastro.xaml └── WPFSimpleDemo.csproj ├── WPFSimpleDemo.Tests ├── DatabaseTests.cs ├── packages.config ├── CustomValidatorsTests.cs ├── Properties │ └── AssemblyInfo.cs ├── App.config └── WPFSimpleDemo.Tests.csproj ├── LICENSE.md ├── WPFSimpleDemo.sln ├── README.md ├── .gitattributes └── .gitignore /Libs/MvvmHelpers-4.04/Julmar.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quicoli/WPFArquitectureDemo/HEAD/Libs/MvvmHelpers-4.04/Julmar.Core.dll -------------------------------------------------------------------------------- /Libs/MvvmHelpers-4.04/JulMar.Wpf.Helpers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quicoli/WPFArquitectureDemo/HEAD/Libs/MvvmHelpers-4.04/JulMar.Wpf.Helpers.dll -------------------------------------------------------------------------------- /Libs/MvvmHelpers-4.04/Julmar.Wpf.Behaviors.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quicoli/WPFArquitectureDemo/HEAD/Libs/MvvmHelpers-4.04/Julmar.Wpf.Behaviors.dll -------------------------------------------------------------------------------- /WPFSimpleDemo/Constants/Messages.cs: -------------------------------------------------------------------------------- 1 | namespace WPFSimpleDemo.Constants 2 | { 3 | public class Messages 4 | { 5 | public const string EditMessage = "EditMessage"; 6 | } 7 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/Messages/EditMessage.cs: -------------------------------------------------------------------------------- 1 | using JulMar.Windows.Mvvm; 2 | 3 | namespace WPFSimpleDemo.Messages 4 | { 5 | public class EditMessage 6 | { 7 | public SimpleViewModel ViewModel { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/Entities/User.cs: -------------------------------------------------------------------------------- 1 | namespace WPFSimpleDemo.Entities 2 | { 3 | public class User: BaseEntity 4 | { 5 | public virtual string UserName { get; set; } 6 | public virtual string Password { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/Persistance/CustomType/IStringCipher.cs: -------------------------------------------------------------------------------- 1 | namespace WPFSimpleDemo.Persistance.CustomType 2 | { 3 | public interface IStringCipher 4 | { 5 | string Encrypt(string text); 6 | string Decrypt(string text); 7 | } 8 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Validation/IPasswordRule.cs: -------------------------------------------------------------------------------- 1 | namespace WPFSimpleDemo.Validation 2 | { 3 | /// 4 | /// Check password follows security rules 5 | /// 6 | public interface IPasswordRule 7 | { 8 | bool Passed(string password); 9 | string ErrorMessage { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /WPFSimpleDemo.Tests/DatabaseTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using NUnit.Framework; 7 | 8 | namespace WPFSimpleDemo.Tests 9 | { 10 | [TestFixture] 11 | public class DatabaseTests 12 | { 13 | [Test] 14 | public void CanCreateDatabaseScheema() 15 | { 16 | Assert.DoesNotThrow(() => 17 | { 18 | var session = Bootstrapper.Initialize(true); 19 | }); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Persistance/NhMapping/UserClassMap.cs: -------------------------------------------------------------------------------- 1 | using FluentNHibernate.Mapping; 2 | using WPFSimpleDemo.Entities; 3 | using WPFSimpleDemo.Persistance.CustomType; 4 | 5 | namespace WPFSimpleDemo.Persistance.NhMapping 6 | { 7 | public class UserClassMap: ClassMap 8 | { 9 | public UserClassMap() 10 | { 11 | Table("UserTable"); 12 | Id(x => x.Id).GeneratedBy.HiLo("50"); 13 | Map(x => x.UserName).Index("UserIdx1"); 14 | Map(x => x.Password).CustomType().Index("UserIdx2"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using NHibernate; 9 | 10 | namespace WPFSimpleDemo 11 | { 12 | /// 13 | /// Interaction logic for App.xaml 14 | /// 15 | public partial class App : Application 16 | { 17 | public static ISessionFactory SessionFactory; 18 | 19 | protected override void OnStartup(StartupEventArgs e) 20 | { 21 | base.OnStartup(e); 22 | SessionFactory = Bootstrapper.Initialize(false); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /WPFSimpleDemo.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Validation/PasswordRuleAttribute.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 | using Microsoft.Practices.ServiceLocation; 8 | 9 | namespace WPFSimpleDemo.Validation 10 | { 11 | public class PasswordRuleAttribute: ValidationAttribute 12 | { 13 | public override bool IsValid(object value) 14 | { 15 | var validator = ServiceLocator.Current.GetInstance(); 16 | var str = value == null ? string.Empty : (string) value; 17 | var isValid = validator.Passed(str); 18 | ErrorMessage = validator.ErrorMessage; 19 | return isValid; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WPFSimpleDemo.Tests/CustomValidatorsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using JetBrains.Annotations; 7 | using NUnit.Framework; 8 | using WPFSimpleDemo.Validation; 9 | 10 | namespace WPFSimpleDemo.Tests 11 | { 12 | [TestFixture] 13 | public class CustomValidatorsTests 14 | { 15 | [Test] 16 | public void DefaultPasswordRuleIsOk() 17 | { 18 | var validator = new DefaultPasswordRule(); 19 | Assert.IsTrue(validator.Passed("A01u03t05v06z07"), "didnt acept valid password"); 20 | Assert.IsFalse(validator.Passed("asefgrgvvv"), "acepted invalid password"); 21 | Assert.IsFalse(validator.Passed(""), "acepted empty password"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 quicoli 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Validation/DefaultPasswordRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WPFSimpleDemo.Validation 8 | { 9 | /// 10 | /// Default password rule verify at least: 11 | /// 1 - One char is uppercase 12 | /// 2 - One char is number 13 | /// 3 - Min. size = 8 14 | /// 15 | public class DefaultPasswordRule: IPasswordRule 16 | { 17 | const string ErrorText = "Password must contain at least: 1 Uppercase letter, 1 number and be 8 characters size"; 18 | public bool Passed(string password) 19 | { 20 | ErrorMessage = string.Empty; 21 | 22 | var isValid = (!string.IsNullOrWhiteSpace(password)) && (password.Any(char.IsUpper) && password.Any(char.IsDigit) && password.Length>=8); 23 | if (!isValid) 24 | { 25 | ErrorMessage = ErrorText; 26 | return false; 27 | } 28 | return true; 29 | } 30 | 31 | public string ErrorMessage { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 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 WPFSimpleDemo.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WPFSimpleDemo/MyServiceLocatorProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Alphacloud.Common.ServiceLocator.Castle; 7 | using Castle.MicroKernel.Registration; 8 | using Castle.Windsor; 9 | using Microsoft.Practices.ServiceLocation; 10 | using WPFSimpleDemo.Persistance.CustomType; 11 | using WPFSimpleDemo.Validation; 12 | 13 | namespace WPFSimpleDemo 14 | { 15 | public class MyServiceLocatorProvider 16 | { 17 | private static WindsorContainer _container = null; 18 | 19 | private MyServiceLocatorProvider() 20 | { 21 | } 22 | 23 | public static WindsorContainer Container 24 | { 25 | get { return _container ?? (_container = new WindsorContainer()); } 26 | set { _container = value; } 27 | 28 | } 29 | 30 | public static void Initialize() 31 | { 32 | var sl = new WindsorServiceLocatorAdapter(Container); 33 | Container.Register(Component.For().ImplementedBy().LifeStyle.Transient); 34 | Container.Register(Component.For().ImplementedBy().LifeStyle.Transient); 35 | ServiceLocator.SetLocatorProvider(() => sl); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Entities/BaseEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WPFSimpleDemo.Entities 4 | { 5 | public class BaseEntity where T : BaseEntity 6 | { 7 | public virtual Int64 Id { get; set; } 8 | 9 | 10 | private int? _hashCode; 11 | public override int GetHashCode() 12 | { 13 | if (_hashCode.HasValue) return _hashCode.Value; 14 | 15 | var ehTransiente = Id == 0; 16 | if (ehTransiente) 17 | { 18 | _hashCode = base.GetHashCode(); 19 | return _hashCode.Value; 20 | } 21 | return Id.GetHashCode(); 22 | } 23 | 24 | public override bool Equals(object obj) 25 | { 26 | var outro = obj as T; 27 | if (outro == null) return false; 28 | 29 | var esteEhTransiente = Id == 0; 30 | var outroEhTransiente = outro.Id == 0; 31 | 32 | if (esteEhTransiente && outroEhTransiente) 33 | return ReferenceEquals(this, outro); 34 | 35 | return Id == outro.Id; 36 | } 37 | 38 | 39 | public static bool operator ==(BaseEntity lhs, BaseEntity rhs) 40 | { 41 | return Equals(lhs, rhs); 42 | } 43 | 44 | 45 | public static bool operator !=(BaseEntity lhs, BaseEntity rhs) 46 | { 47 | return !Equals(lhs, rhs); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /WPFSimpleDemo.Tests/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("WPFSimpleDemo.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WPFSimpleDemo.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 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("a6c76aba-6f22-4bf3-a56c-ee6fa7c2dad0")] 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 | -------------------------------------------------------------------------------- /WPFSimpleDemo/MainWindow.xaml.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.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | using JulMar.Core; 16 | using JulMar.Core.Interfaces; 17 | using JulMar.Windows.Mvvm; 18 | using WPFSimpleDemo.Messages; 19 | 20 | namespace WPFSimpleDemo 21 | { 22 | /// 23 | /// Interaction logic for MainWindow.xaml 24 | /// 25 | public partial class MainWindow : Window 26 | { 27 | private IMessageMediator _messageMediator = ViewModel.ServiceProvider.Resolve(); 28 | 29 | public MainWindow() 30 | { 31 | InitializeComponent(); 32 | _messageMediator.Register(this); 33 | DataContext = new MainViewModel(); 34 | } 35 | 36 | [MessageMediatorTarget(Constants.Messages.EditMessage)] 37 | public void OnEditing(EditMessage message) 38 | { 39 | if (message.ViewModel == DataContext) 40 | { 41 | TextBoxUserName.Focus(); 42 | Keyboard.Focus(TextBoxUserName); 43 | } 44 | } 45 | 46 | private void MainWindow_OnUnloaded(object sender, RoutedEventArgs e) 47 | { 48 | _messageMediator.Unregister(this); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /WPFSimpleDemo/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /WPFSimpleDemo.Tests/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /WPFSimpleDemo/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /WPFSimpleDemo.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFSimpleDemo", "WPFSimpleDemo\WPFSimpleDemo.csproj", "{D61388A4-688D-4A64-8B19-7A55C8E3FACA}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFSimpleDemo.Tests", "WPFSimpleDemo.Tests\WPFSimpleDemo.Tests.csproj", "{A6C76ABA-6F22-4BF3-A56C-EE6FA7C2DAD0}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {D61388A4-688D-4A64-8B19-7A55C8E3FACA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {D61388A4-688D-4A64-8B19-7A55C8E3FACA}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {D61388A4-688D-4A64-8B19-7A55C8E3FACA}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {D61388A4-688D-4A64-8B19-7A55C8E3FACA}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {A6C76ABA-6F22-4BF3-A56C-EE6FA7C2DAD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {A6C76ABA-6F22-4BF3-A56C-EE6FA7C2DAD0}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {A6C76ABA-6F22-4BF3-A56C-EE6FA7C2DAD0}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {A6C76ABA-6F22-4BF3-A56C-EE6FA7C2DAD0}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | EnterpriseLibraryConfigurationToolBinariesPathV6 = packages\EnterpriseLibrary.Common.6.0.1304.0\lib\NET45;packages\EnterpriseLibrary.Validation.6.0.1304.0\lib\NET45;packages\EnterpriseLibrary.Validation.Integration.WPF.6.0.1304.0\lib\NET45 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /WPFSimpleDemo/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Model/UserModel.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 | using Microsoft.Practices.EnterpriseLibrary.Validation; 8 | using Microsoft.Practices.EnterpriseLibrary.Validation.Validators; 9 | using WPFSimpleDemo.Validation; 10 | using ValidationResult = Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResult; 11 | 12 | namespace WPFSimpleDemo.Model 13 | { 14 | [HasSelfValidation] 15 | public class UserModel: BaseModel 16 | { 17 | private long _id; 18 | private string _userName; 19 | private string _password; 20 | private string _confirmPassword; 21 | 22 | public long Id 23 | { 24 | get { return _id; } 25 | set { _id = value; OnPropertyChanged(()=> Id);} 26 | } 27 | 28 | [Required(ErrorMessage = "User name is required")] 29 | public string UserName 30 | { 31 | get { return _userName; } 32 | set { _userName = value; OnPropertyChanged(()=>UserName); OnPropertyChanged();} 33 | } 34 | 35 | [PasswordRule] 36 | public string Password 37 | { 38 | get { return _password; } 39 | set { _password = value; OnPropertyChanged(()=>Password); } 40 | } 41 | 42 | public string ConfirmPassword 43 | { 44 | get { return _confirmPassword; } 45 | set { _confirmPassword = value; OnPropertyChanged(()=>ConfirmPassword); } 46 | } 47 | 48 | 49 | [SelfValidation] 50 | public void Validate(ValidationResults validationResults) 51 | { 52 | if (string.IsNullOrWhiteSpace(ConfirmPassword)) 53 | { 54 | validationResults.AddResult( 55 | new ValidationResult("Required!", this, "ConfirmPassword", null,null)); 56 | 57 | } 58 | 59 | if (ConfirmPassword != Password) 60 | { 61 | validationResults.AddResult( 62 | new ValidationResult("Confirmation and Password doesn't match!", this, "ConfirmPassword", null, null)); 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## A Simple WPF Architecture Demo 2 | 3 | Some years ago I wrote an [article](http://www.devmedia.com.br/mandamentos-da-orientacao-a-objetos-artigo-net-magazine-79/18481) for [DevMedia group](http://www.devmedia.com.br/) named "Comandments of Object Orientation", based in what I'd worked, learned, read, and studied. So I can say: 4 | 5 | _The goal of this project is to show how build a good (flexible) solution for WPF applications._ 6 | 7 | Well, this is not a silver bullet, but it's a starting point and I'd like to let an open discussion here. 8 | 9 | ![](http://g.recordit.co/OKOhx9TYTx.gif "Simple application") 10 | 11 | ## What you can see 12 | - How to keep logic in ViewModel, avoiding code-behind 13 | - Use commands to abstract user actions 14 | - Dispatch specific messages (message mediator pattern) to accomplish specific actions 15 | - UI message services 16 | - Program to interface, not implementation 17 | - Model validation 18 | - NHibernate (in a simple way) 19 | - Mapping Models->Entities and Entities<-Models 20 | 21 | In the next days I'm creating some wikis explaining the code 22 | 23 | ## What is inside 24 | 25 | This is an one Window only application using the following packages: 26 | 27 | - MVVMHelper, a MVVM framework I like (binaries included). 28 | - [Material Design](http://materialdesigninxaml.net/) UI style. 29 | - [Castle Windsor](http://www.castleproject.org/) Inversion of Control container. 30 | - [NHibernate](http://nhibernate.info/) for data persistance. 31 | - [Fluent NHibernate](http://www.fluentnhibernate.org/) for class mapping. 32 | - [SQLite](https://system.data.sqlite.org/index.html/doc/trunk/www/index.wiki) as database. 33 | - [AutoMapper](http://automapper.org/) for mapping one object to another (Models to Entities/Entities to Models). 34 | - [NUnit](http://nunit.org/) for some unit tests. 35 | 36 | All packages available by nuget, except MVVMHelper (binaries included) 37 | 38 | ##Instructions 39 | 40 | As SQLite database is not created, open App.xml.cs and change this line: 41 | 42 | SessionFactory = Bootstrapper.Initialize(false); 43 | 44 | to 45 | 46 | SessionFactory = Bootstrapper.Initialize(true); 47 | 48 | and run the application, 49 | so database will be created. 50 | 51 | After first run you can change back to 52 | 53 | 54 | SessionFactory = Bootstrapper.Initialize(false); 55 | 56 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("WPFSimpleDemo")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("WPFSimpleDemo")] 15 | [assembly: AssemblyCopyright("Copyright © 2016")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Bootstrapper.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using FluentNHibernate.Cfg; 3 | using FluentNHibernate.Cfg.Db; 4 | using NHibernate; 5 | using NHibernate.Cfg; 6 | using NHibernate.Tool.hbm2ddl; 7 | using WPFSimpleDemo.Entities; 8 | using WPFSimpleDemo.Model; 9 | using WPFSimpleDemo.Persistance.NhMapping; 10 | 11 | namespace WPFSimpleDemo 12 | { 13 | public static class Bootstrapper 14 | { 15 | public static IMapper Mapper { get; set; } 16 | private static ISessionFactory _sessionFactory; 17 | 18 | private static void InitializeAutoMapper() 19 | { 20 | var config = new MapperConfiguration(cfg => 21 | { 22 | cfg.CreateMap() 23 | .ForMember(s => s.IsValid, c => c.Ignore()) 24 | .ForMember(s => s.ValidationResults, c => c.Ignore()) 25 | .ForMember(s => s.ConfirmPassword, c => c.ResolveUsing(y => y.Password)); 26 | 27 | 28 | cfg.CreateMap() 29 | .ForSourceMember(s => s.IsValid, c => c.Ignore()) 30 | .ForSourceMember(s => s.ValidationResults, c => c.Ignore()); 31 | 32 | }); 33 | 34 | config.AssertConfigurationIsValid(); 35 | Mapper = config.CreateMapper(); 36 | } 37 | 38 | private static ISessionFactory InitializePersistance(bool createSchema) 39 | { 40 | if (_sessionFactory != null) 41 | { 42 | return _sessionFactory; 43 | } 44 | 45 | var fluentConfig = Fluently.Configure() 46 | .Database(SQLiteConfiguration.Standard.UsingFile("userdb.db").ShowSql()) 47 | .Mappings(mapper => 48 | { 49 | mapper.FluentMappings 50 | .AddFromAssemblyOf(); 51 | }); 52 | 53 | var nhConfiguration = fluentConfig.BuildConfiguration(); 54 | _sessionFactory = nhConfiguration.BuildSessionFactory(); 55 | 56 | if (createSchema) 57 | { 58 | using (var session = _sessionFactory.OpenSession()) 59 | { 60 | using (var tx = session.BeginTransaction()) 61 | { 62 | new SchemaExport(nhConfiguration).Execute(true, true, false, session.Connection, null); 63 | tx.Commit(); 64 | } 65 | } 66 | } 67 | 68 | return _sessionFactory; 69 | } 70 | 71 | 72 | public static ISessionFactory Initialize(bool createSchema) 73 | { 74 | MyServiceLocatorProvider.Initialize(); 75 | InitializeAutoMapper(); 76 | return InitializePersistance(createSchema); 77 | } 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/Persistance/CustomType/EncryptedString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | using Microsoft.Practices.ServiceLocation; 4 | using NHibernate; 5 | using NHibernate.SqlTypes; 6 | using NHibernate.UserTypes; 7 | 8 | namespace WPFSimpleDemo.Persistance.CustomType 9 | { 10 | public class EncryptedString : IUserType 11 | { 12 | private const string Pass = "XYZO1"; 13 | 14 | public new bool Equals(object x, object y) 15 | { 16 | if (ReferenceEquals(x, y)) 17 | { 18 | return true; 19 | } 20 | if (x == null || y == null) 21 | { 22 | return false; 23 | } 24 | return x.Equals(y); 25 | 26 | } 27 | 28 | public int GetHashCode(object x) 29 | { 30 | throw new NotImplementedException(); 31 | } 32 | 33 | public object NullSafeGet(IDataReader rs, string[] names, object owner) 34 | { 35 | object passwordString = NHibernateUtil.String.NullSafeGet(rs, names[0]); 36 | return passwordString != null ? ServiceLocator.Current.GetInstance().Decrypt((string)passwordString) : null; 37 | } 38 | 39 | public void NullSafeSet(IDbCommand cmd, object value, int index) 40 | { 41 | if (value == null) 42 | { 43 | NHibernateUtil.String.NullSafeSet(cmd, null, index); 44 | return; 45 | } 46 | string encryptedValue = ServiceLocator.Current.GetInstance().Encrypt((string)value); 47 | NHibernateUtil.String.NullSafeSet(cmd, encryptedValue, index); 48 | } 49 | 50 | public object DeepCopy(object value) 51 | { 52 | return value == null ? null : string.Copy((string)value); 53 | } 54 | 55 | public object Replace(object original, object target, object owner) 56 | { 57 | return original; 58 | } 59 | 60 | public object Assemble(object cached, object owner) 61 | { 62 | return DeepCopy(cached); 63 | } 64 | 65 | public object Disassemble(object value) 66 | { 67 | return DeepCopy(value); 68 | } 69 | 70 | public SqlType[] SqlTypes 71 | { 72 | get { return new[] { new SqlType(DbType.String) }; } 73 | } 74 | 75 | public Type ReturnedType 76 | { 77 | get { return typeof(string); } 78 | } 79 | 80 | public bool IsMutable 81 | { 82 | get { return false; } 83 | } 84 | 85 | public int GetHasCode(object x) 86 | { 87 | if (x == null) 88 | { 89 | throw new ArgumentNullException("x"); 90 | } 91 | return x.GetHashCode(); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 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 WPFSimpleDemo.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WPFSimpleDemo.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Persistance/CustomType/DefaultStringCipher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Security.Cryptography; 4 | using System.Text; 5 | 6 | namespace WPFSimpleDemo.Persistance.CustomType 7 | { 8 | public class DefaultStringCipher:IStringCipher 9 | { 10 | 11 | private static readonly byte[] initVectorBytes = Encoding.ASCII.GetBytes("tu89geji340t89u2"); 12 | private const int Keysize = 256; 13 | private const string PassPhrase = "XYZO1"; 14 | 15 | public string Encrypt(string text) 16 | { 17 | byte[] plainTextBytes = Encoding.UTF8.GetBytes(text); 18 | using (PasswordDeriveBytes password = new PasswordDeriveBytes(PassPhrase, null)) 19 | { 20 | byte[] keyBytes = password.GetBytes(Keysize / 8); 21 | using (RijndaelManaged symmetricKey = new RijndaelManaged()) 22 | { 23 | symmetricKey.Mode = CipherMode.CBC; 24 | using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)) 25 | { 26 | using (MemoryStream memoryStream = new MemoryStream()) 27 | { 28 | using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) 29 | { 30 | cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 31 | cryptoStream.FlushFinalBlock(); 32 | byte[] cipherTextBytes = memoryStream.ToArray(); 33 | return Convert.ToBase64String(cipherTextBytes); 34 | } 35 | } 36 | } 37 | } 38 | } 39 | } 40 | 41 | public string Decrypt(string text) 42 | { 43 | byte[] cipherTextBytes = Convert.FromBase64String(text); 44 | using (PasswordDeriveBytes password = new PasswordDeriveBytes(PassPhrase, null)) 45 | { 46 | byte[] keyBytes = password.GetBytes(Keysize / 8); 47 | using (RijndaelManaged symmetricKey = new RijndaelManaged()) 48 | { 49 | symmetricKey.Mode = CipherMode.CBC; 50 | using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)) 51 | { 52 | using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes)) 53 | { 54 | using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) 55 | { 56 | byte[] plainTextBytes = new byte[cipherTextBytes.Length]; 57 | int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); 58 | return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); 59 | } 60 | } 61 | } 62 | } 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/Model/BaseModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Specialized; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | using System.Reflection; 7 | using JulMar.Windows.Mvvm; 8 | using Microsoft.Practices.EnterpriseLibrary.Validation; 9 | 10 | namespace WPFSimpleDemo.Model 11 | { 12 | 13 | public class BaseModel : ViewModel, IEditableObject, IDataErrorInfo 14 | { 15 | 16 | /// 17 | /// Utilizado para manter o estado do objeto antes de sofrer alguma 18 | /// alteração 19 | /// 20 | private HybridDictionary _oldState; 21 | 22 | protected ValidationResults _validationResults; 23 | 24 | 25 | public ValidationResults ValidationResults 26 | { get { return _validationResults; } set { _validationResults = value; } } 27 | 28 | private bool _isValid; 29 | 30 | public BaseModel() 31 | { 32 | UpdateValidationState(); 33 | } 34 | 35 | protected override void OnPropertyChanged(Expression> propExpr) 36 | { 37 | base.OnPropertyChanged(propExpr); 38 | UpdateValidationState(); 39 | IsValid = _validationResults.IsValid; 40 | } 41 | public void UpdateValidationState() 42 | { 43 | Validator validator = ValidationFactory.CreateValidator(); 44 | _validationResults = validator.Validate(this); 45 | IsValid = _validationResults.IsValid; 46 | } 47 | 48 | public void ClearValidationState() 49 | { 50 | _validationResults = new ValidationResults(); 51 | IsValid = true; 52 | } 53 | 54 | public bool IsValid 55 | { 56 | get { return _isValid; } 57 | set 58 | { 59 | _isValid = value; 60 | base.OnPropertyChanged(() => IsValid); 61 | } 62 | } 63 | 64 | 65 | /// 66 | /// Deve ser chamado antes de se efetuar alguma alteração no 67 | /// objeto 68 | /// 69 | /// 70 | /// Exemplo: 71 | /// 72 | /// 73 | /// 74 | /// var obj = new ObjetoQueImplementaBindableEditabelEntity(); 75 | /// obj.BeginEdit() 76 | /// obj.Nome = "Teste"; 77 | /// 78 | /// 79 | /// 80 | /// Para finalizar a edição dos dados do objeto usa-se 81 | /// Para cancelar a edição dos dados do objeto usa-se 82 | /// 83 | public virtual void BeginEdit() 84 | { 85 | _oldState = new HybridDictionary(); 86 | foreach (PropertyInfo property in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) 87 | { 88 | if (property.CanWrite) 89 | { 90 | _oldState[property.Name] = property.GetValue(this, null); 91 | } 92 | } 93 | } 94 | 95 | 96 | 97 | public virtual void EndEdit() 98 | { 99 | _oldState = null; 100 | 101 | } 102 | 103 | public virtual void CancelEdit() 104 | { 105 | if (_oldState == null) return; 106 | 107 | foreach (PropertyInfo property in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) 108 | { 109 | if (property.CanWrite) 110 | { 111 | property.SetValue(this, _oldState[property.Name], null); 112 | base.OnPropertyChanged(property.Name); 113 | } 114 | } 115 | _oldState = null; 116 | UpdateValidationState(); 117 | 118 | } 119 | 120 | public virtual string this[string columnName] 121 | { 122 | get 123 | { 124 | string message = null; 125 | var filteredResults = new ValidationResults(); 126 | 127 | var result = _validationResults.FirstOrDefault(x => x.Key == columnName); 128 | if (result != null) 129 | { 130 | filteredResults.AddResult(result); 131 | message = filteredResults.First().Message; 132 | 133 | } 134 | return message; 135 | } 136 | } 137 | 138 | public virtual string Error 139 | { 140 | get { return null; } 141 | } 142 | } 143 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | [Ss]tyle[Cc]op.* 182 | ~$* 183 | *~ 184 | *.dbmdl 185 | *.dbproj.schemaview 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # RIA/Silverlight projects 192 | Generated_Code/ 193 | 194 | # Backup & report files from converting an old project file 195 | # to a newer Visual Studio version. Backup files are not needed, 196 | # because we have git ;-) 197 | _UpgradeReport_Files/ 198 | Backup*/ 199 | UpgradeLog*.XML 200 | UpgradeLog*.htm 201 | 202 | # SQL Server files 203 | *.mdf 204 | *.ldf 205 | 206 | # Business Intelligence projects 207 | *.rdl.data 208 | *.bim.layout 209 | *.bim_*.settings 210 | 211 | # Microsoft Fakes 212 | FakesAssemblies/ 213 | 214 | # GhostDoc plugin setting file 215 | *.GhostDoc.xml 216 | 217 | # Node.js Tools for Visual Studio 218 | .ntvs_analysis.dat 219 | 220 | # Visual Studio 6 build log 221 | *.plg 222 | 223 | # Visual Studio 6 workspace options file 224 | *.opt 225 | 226 | # Visual Studio LightSwitch build output 227 | **/*.HTMLClient/GeneratedArtifacts 228 | **/*.DesktopClient/GeneratedArtifacts 229 | **/*.DesktopClient/ModelManifest.xml 230 | **/*.Server/GeneratedArtifacts 231 | **/*.Server/ModelManifest.xml 232 | _Pvt_Extensions 233 | 234 | # LightSwitch generated files 235 | GeneratedArtifacts/ 236 | ModelManifest.xml 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | 241 | # FAKE - F# Make 242 | .fake/ 243 | -------------------------------------------------------------------------------- /WPFSimpleDemo/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 39 | 40 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 64 | 65 | 66 | 67 | 70 | 71 | 72 | 73 | 74 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /WPFSimpleDemo/Helpers/BindingListSortable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Reflection; 6 | 7 | namespace WPFSimpleDemo.Helpers 8 | { 9 | 10 | /// 11 | /// Classe especializada que permite a ordenação em um DataGrid 12 | /// Fonte: http://www.timvw.be/2008/08/02/presenting-the-sortablebindinglistt-take-two/ 13 | /// 14 | /// 15 | public class BindingListSortable : BindingList 16 | { 17 | private readonly Dictionary> comparers; 18 | private bool isSorted; 19 | private ListSortDirection listSortDirection; 20 | private PropertyDescriptor propertyDescriptor; 21 | 22 | public BindingListSortable() 23 | : base(new List()) 24 | { 25 | this.comparers = new Dictionary>(); 26 | } 27 | 28 | public BindingListSortable(IEnumerable enumeration) 29 | : base(new List(enumeration)) 30 | { 31 | this.comparers = new Dictionary>(); 32 | } 33 | 34 | protected override bool SupportsSortingCore 35 | { 36 | get { return true; } 37 | } 38 | 39 | protected override bool IsSortedCore 40 | { 41 | get { return this.isSorted; } 42 | } 43 | 44 | protected override PropertyDescriptor SortPropertyCore 45 | { 46 | get { return this.propertyDescriptor; } 47 | } 48 | 49 | protected override ListSortDirection SortDirectionCore 50 | { 51 | get { return this.listSortDirection; } 52 | } 53 | 54 | protected override bool SupportsSearchingCore 55 | { 56 | get { return true; } 57 | } 58 | 59 | protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction) 60 | { 61 | List itemsList = (List)this.Items; 62 | 63 | Type propertyType = property.PropertyType; 64 | PropertyComparer comparer; 65 | if (!this.comparers.TryGetValue(propertyType, out comparer)) 66 | { 67 | comparer = new PropertyComparer(property, direction); 68 | this.comparers.Add(propertyType, comparer); 69 | } 70 | 71 | comparer.SetPropertyAndDirection(property, direction); 72 | itemsList.Sort(comparer); 73 | 74 | this.propertyDescriptor = property; 75 | this.listSortDirection = direction; 76 | this.isSorted = true; 77 | 78 | this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); 79 | } 80 | 81 | protected override void RemoveSortCore() 82 | { 83 | this.isSorted = false; 84 | this.propertyDescriptor = base.SortPropertyCore; 85 | this.listSortDirection = base.SortDirectionCore; 86 | 87 | this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); 88 | } 89 | 90 | protected override int FindCore(PropertyDescriptor property, object key) 91 | { 92 | int count = this.Count; 93 | for (int i = 0; i < count; ++i) 94 | { 95 | T element = this[i]; 96 | if (property.GetValue(element).Equals(key)) 97 | { 98 | return i; 99 | } 100 | } 101 | 102 | return -1; 103 | } 104 | } 105 | 106 | 107 | public class PropertyComparer : IComparer 108 | { 109 | private readonly IComparer comparer; 110 | private PropertyDescriptor propertyDescriptor; 111 | private int reverse; 112 | 113 | public PropertyComparer(PropertyDescriptor property, ListSortDirection direction) 114 | { 115 | this.propertyDescriptor = property; 116 | Type comparerForPropertyType = typeof(Comparer<>).MakeGenericType(property.PropertyType); 117 | this.comparer = (IComparer)comparerForPropertyType.InvokeMember("Default", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public, null, null, null); 118 | this.SetListSortDirection(direction); 119 | } 120 | 121 | #region IComparer Members 122 | 123 | public int Compare(T x, T y) 124 | { 125 | return this.reverse * this.comparer.Compare(this.propertyDescriptor.GetValue(x), this.propertyDescriptor.GetValue(y)); 126 | } 127 | 128 | #endregion 129 | 130 | private void SetPropertyDescriptor(PropertyDescriptor descriptor) 131 | { 132 | this.propertyDescriptor = descriptor; 133 | } 134 | 135 | private void SetListSortDirection(ListSortDirection direction) 136 | { 137 | this.reverse = direction == ListSortDirection.Ascending ? 1 : -1; 138 | } 139 | 140 | public void SetPropertyAndDirection(PropertyDescriptor descriptor, ListSortDirection direction) 141 | { 142 | this.SetPropertyDescriptor(descriptor); 143 | this.SetListSortDirection(direction); 144 | } 145 | } 146 | 147 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/Behaviors/PasswordBoxHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | 4 | namespace WPFSimpleDemo.Behaviors 5 | { 6 | /// 7 | /// This class adds binding capabilities to the standard WPF PasswordBox. 8 | /// 9 | /// 10 | /// http://www.codeproject.com/Articles/37167/Binding-Passwords.aspx 11 | /// 12 | public static class PasswordBoxHelper 13 | { 14 | #region · Attached Properties · 15 | 16 | public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached( 17 | "BindPassword", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false, OnBindPasswordChanged)); 18 | 19 | private static readonly DependencyProperty UpdatingPassword = 20 | DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false)); 21 | 22 | /// 23 | /// BoundPassword Attached Dependency Property 24 | /// 25 | public static readonly DependencyProperty BoundPasswordProperty = 26 | DependencyProperty.RegisterAttached("BoundPassword", 27 | typeof(string), 28 | typeof(PasswordBoxHelper), 29 | new FrameworkPropertyMetadata(string.Empty, OnBoundPasswordChanged)); 30 | 31 | #endregion 32 | 33 | #region · Attached Property Get/Set Methods · 34 | 35 | public static void SetBindPassword(DependencyObject dp, bool value) 36 | { 37 | dp.SetValue(BindPassword, value); 38 | } 39 | 40 | public static bool GetBindPassword(DependencyObject dp) 41 | { 42 | return (bool)dp.GetValue(BindPassword); 43 | } 44 | 45 | private static bool GetUpdatingPassword(DependencyObject dp) 46 | { 47 | return (bool)dp.GetValue(UpdatingPassword); 48 | } 49 | 50 | private static void SetUpdatingPassword(DependencyObject dp, bool value) 51 | { 52 | dp.SetValue(UpdatingPassword, value); 53 | } 54 | 55 | /// 56 | /// Gets the BoundPassword property. 57 | /// 58 | public static string GetBoundPassword(DependencyObject d) 59 | { 60 | return (string)d.GetValue(BoundPasswordProperty); 61 | } 62 | 63 | /// 64 | /// Sets the BoundPassword property. 65 | /// 66 | public static void SetBoundPassword(DependencyObject d, string value) 67 | { 68 | d.SetValue(BoundPasswordProperty, value); 69 | } 70 | 71 | #endregion 72 | 73 | #region · Attached Properties Callbacks · 74 | 75 | private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 76 | { 77 | PasswordBox box = d as PasswordBox; 78 | 79 | // only handle this event when the property is attached to a PasswordBox 80 | // and when the BindPassword attached property has been set to true 81 | if (d == null || !GetBindPassword(d)) 82 | { 83 | return; 84 | } 85 | 86 | // avoid recursive updating by ignoring the box's changed event 87 | box.PasswordChanged -= HandlePasswordChanged; 88 | 89 | string newPassword = (string)e.NewValue; 90 | 91 | if (!GetUpdatingPassword(box)) 92 | { 93 | box.Password = newPassword; 94 | } 95 | 96 | if (box.Template != null) 97 | { 98 | var controle = box.Template.FindName("PART_TextBlock_Control", box) as TextBlock; 99 | 100 | if (controle != null && e.NewValue != null) 101 | { 102 | controle.Text = e.NewValue.ToString().Length > 0 ? "********" : string.Empty; 103 | } 104 | } 105 | 106 | box.PasswordChanged += HandlePasswordChanged; 107 | } 108 | 109 | private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e) 110 | { 111 | // when the BindPassword attached property is set on a PasswordBox, 112 | // start listening to its PasswordChanged event 113 | 114 | PasswordBox box = dp as PasswordBox; 115 | 116 | if (box == null) 117 | { 118 | return; 119 | } 120 | 121 | bool wasBound = (bool)(e.OldValue); 122 | bool needToBind = (bool)(e.NewValue); 123 | 124 | if (wasBound) 125 | { 126 | box.PasswordChanged -= HandlePasswordChanged; 127 | } 128 | 129 | if (needToBind) 130 | { 131 | box.PasswordChanged += HandlePasswordChanged; 132 | } 133 | } 134 | 135 | private static void HandlePasswordChanged(object sender, RoutedEventArgs e) 136 | { 137 | PasswordBox box = sender as PasswordBox; 138 | 139 | // set a flag to indicate that we're updating the password 140 | SetUpdatingPassword(box, true); 141 | // push the new password into the BoundPassword property 142 | SetBoundPassword(box, box.Password); 143 | SetUpdatingPassword(box, false); 144 | } 145 | 146 | #endregion 147 | } 148 | } -------------------------------------------------------------------------------- /WPFSimpleDemo/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 | -------------------------------------------------------------------------------- /WPFSimpleDemo.Tests/WPFSimpleDemo.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A6C76ABA-6F22-4BF3-A56C-EE6FA7C2DAD0} 8 | Library 9 | Properties 10 | WPFSimpleDemo.Tests 11 | WPFSimpleDemo.Tests 12 | v4.6.1 13 | 512 14 | 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll 37 | True 38 | 39 | 40 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll 41 | True 42 | 43 | 44 | ..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll 45 | True 46 | 47 | 48 | False 49 | ..\Libs\MvvmHelpers-4.04\JulMar.Wpf.Helpers.dll 50 | 51 | 52 | ..\packages\NHibernate.4.0.0.4000\lib\net40\NHibernate.dll 53 | True 54 | 55 | 56 | ..\packages\NUnit.2.6.4\lib\nunit.framework.dll 57 | True 58 | 59 | 60 | 61 | 62 | 63 | 64 | ..\packages\System.Data.SQLite.Core.1.0.103\lib\net46\System.Data.SQLite.dll 65 | True 66 | 67 | 68 | ..\packages\System.Data.SQLite.EF6.1.0.103\lib\net46\System.Data.SQLite.EF6.dll 69 | True 70 | 71 | 72 | ..\packages\System.Data.SQLite.Linq.1.0.103\lib\net46\System.Data.SQLite.Linq.dll 73 | True 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | {d61388a4-688d-4a64-8b19-7a55c8e3faca} 92 | WPFSimpleDemo 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 104 | 105 | 106 | 107 | 114 | -------------------------------------------------------------------------------- /WPFSimpleDemo/MainViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Castle.Components.DictionaryAdapter; 8 | using JulMar.Core.Interfaces; 9 | using JulMar.Windows.Interfaces; 10 | using JulMar.Windows.Mvvm; 11 | using NHibernate.Linq; 12 | using WPFSimpleDemo.Entities; 13 | using WPFSimpleDemo.Helpers; 14 | using WPFSimpleDemo.Messages; 15 | using WPFSimpleDemo.Model; 16 | 17 | namespace WPFSimpleDemo 18 | { 19 | public class MainViewModel : ViewModel 20 | { 21 | private UserModel _user; 22 | private UserModel _selectedUser; 23 | private BindingListSortable _userList; 24 | private bool _isBusy; 25 | private bool _isEditing; 26 | 27 | public DelegatingCommand CmdInsert { get; set; } 28 | public DelegatingCommand CmdEdit { get; set; } 29 | public DelegatingCommand CmdCancel { get; set; } 30 | public DelegatingCommand CmdDelete { get; set; } 31 | public DelegatingCommand CmdSave { get; set; } 32 | 33 | 34 | public MainViewModel() 35 | { 36 | CmdInsert = new DelegatingCommand(DoInsert, CanDoInsert); 37 | CmdEdit = new DelegatingCommand(DoEdit, CanDoEdit); 38 | CmdCancel = new DelegatingCommand(DoCancel, CandDoCancel); 39 | CmdDelete = new DelegatingCommand(DoDelete, CanDoDelete); 40 | CmdSave = new DelegatingCommand(DoSave, CanDoSave); 41 | LoadUsers(); 42 | } 43 | 44 | private void LoadUsers() 45 | { 46 | var list = new List(); 47 | using (var session = App.SessionFactory.OpenSession()) 48 | { 49 | using (var tx = session.BeginTransaction()) 50 | { 51 | try 52 | { 53 | list = session.Query().ToList(); 54 | tx.Commit(); 55 | } 56 | catch (Exception) 57 | { 58 | tx.Rollback(); 59 | throw; 60 | } 61 | } 62 | } 63 | UserList = new BindingListSortable(Bootstrapper.Mapper.Map, List>(list)); 64 | } 65 | 66 | 67 | public UserModel User 68 | { 69 | get { return _user; } 70 | set 71 | { 72 | _user = value; 73 | OnPropertyChanged(() => User); 74 | } 75 | } 76 | 77 | public UserModel SelectedUser 78 | { 79 | get { return _selectedUser; } 80 | set 81 | { 82 | _selectedUser = value; 83 | OnPropertyChanged(() => SelectedUser); 84 | if (!IsEditing) 85 | User = SelectedUser; 86 | 87 | } 88 | } 89 | 90 | public BindingListSortable UserList 91 | { 92 | get { return _userList; } 93 | set 94 | { 95 | _userList = value; 96 | OnPropertyChanged(() => UserList); 97 | } 98 | } 99 | 100 | public bool IsBusy 101 | { 102 | get { return _isBusy; } 103 | set 104 | { 105 | _isBusy = value; 106 | OnPropertyChanged(() => IsBusy); 107 | } 108 | } 109 | 110 | public bool IsEditing 111 | { 112 | get { return _isEditing; } 113 | set 114 | { 115 | _isEditing = value; 116 | OnPropertyChanged(() => IsEditing); 117 | if (_isEditing) 118 | Resolve() 119 | .SendMessage(Constants.Messages.EditMessage, new EditMessage() {ViewModel = this}); 120 | } 121 | } 122 | 123 | 124 | private void DoInsert() 125 | { 126 | IsEditing = true; 127 | User = new UserModel(); 128 | User.BeginEdit(); 129 | } 130 | 131 | private bool CanDoInsert() 132 | { 133 | return !IsBusy && !IsEditing; 134 | } 135 | 136 | private void DoEdit() 137 | { 138 | IsEditing = true; 139 | User.BeginEdit(); 140 | } 141 | 142 | private bool CanDoEdit() 143 | { 144 | return !IsBusy && !IsEditing && User != null && User.Id > 0; 145 | } 146 | 147 | private void DoCancel() 148 | { 149 | User.CancelEdit(); 150 | IsEditing = false; 151 | } 152 | 153 | private bool CandDoCancel() 154 | { 155 | return !IsBusy && IsEditing && User != null; 156 | } 157 | 158 | private void DoDelete() 159 | { 160 | if (Resolve().Show("Attention", "Delete selected user?", MessageButtons.YesNo) == 161 | MessageResult.No) 162 | return; 163 | 164 | using (var session = App.SessionFactory.OpenSession()) 165 | { 166 | using (var tx = session.BeginTransaction()) 167 | { 168 | try 169 | { 170 | var user = Bootstrapper.Mapper.Map(User); 171 | session.Delete(user); 172 | tx.Commit(); 173 | UserList.Remove(User); 174 | UserList.ResetBindings(); 175 | User = new UserModel(); 176 | } 177 | catch (Exception ex) 178 | { 179 | tx.Rollback(); 180 | Resolve().Show("Error", ex.Message, MessageButtons.OK); 181 | } 182 | } 183 | } 184 | } 185 | 186 | private bool CanDoDelete() 187 | { 188 | return !IsBusy && !IsEditing && User != null; 189 | } 190 | 191 | private void DoSave() 192 | { 193 | try 194 | { 195 | var user = Bootstrapper.Mapper.Map(User); 196 | using (var session = App.SessionFactory.OpenSession()) 197 | { 198 | using (var tx = session.BeginTransaction()) 199 | { 200 | session.SaveOrUpdate(user); 201 | try 202 | { 203 | tx.Commit(); 204 | } 205 | catch (Exception) 206 | { 207 | tx.Rollback(); 208 | throw; 209 | } 210 | } 211 | } 212 | 213 | User.Id = user.Id; 214 | User.EndEdit(); 215 | UserList.Add(User); 216 | UserList.ResetBindings(); 217 | IsEditing = false; 218 | } 219 | catch (Exception ex) 220 | { 221 | Resolve().Show("Error", ex.Message, MessageButtons.OK); 222 | } 223 | } 224 | 225 | private bool CanDoSave() 226 | { 227 | return !IsBusy && IsEditing && User!=null && User.IsValid; 228 | } 229 | 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /WPFSimpleDemo/CustomControls/TooolBarCadastro.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | using System.Windows.Input; 5 | 6 | namespace WPFSimpleDemo.CustomControls 7 | { 8 | /// 9 | /// Interaction logic for TooolBarCadastro.xaml 10 | /// 11 | public partial class TooolBarCadastro : UserControl 12 | { 13 | public TooolBarCadastro() 14 | { 15 | InitializeComponent(); 16 | } 17 | 18 | [Bindable(true)] 19 | public ICommand CmdInserir 20 | { 21 | get { return (ICommand)GetValue(CmdInserirProperty); } 22 | set 23 | { 24 | SetValue(CmdInserirProperty, value); 25 | } 26 | } 27 | 28 | [Bindable(true)] 29 | public ICommand CmdEditar 30 | { 31 | get { return (ICommand)GetValue(CmdEditarProperty); } 32 | set 33 | { 34 | SetValue(CmdEditarProperty, value); 35 | } 36 | } 37 | 38 | [Bindable(true)] 39 | public ICommand CmdExcluir 40 | { 41 | get { return (ICommand)GetValue(CmdExcluirProperty); } 42 | set 43 | { 44 | SetValue(CmdExcluirProperty, value); 45 | } 46 | } 47 | 48 | [Bindable(true)] 49 | public ICommand CmdSalvar 50 | { 51 | get { return (ICommand)GetValue(CmdSalvarProperty); } 52 | set 53 | { 54 | SetValue(CmdSalvarProperty, value); 55 | } 56 | } 57 | 58 | [Bindable(true)] 59 | public ICommand CmdPesquisar 60 | { 61 | get { return (ICommand)GetValue(CmdPesquisarProperty); } 62 | set 63 | { 64 | SetValue(CmdPesquisarProperty, value); 65 | } 66 | } 67 | 68 | [Bindable(true)] 69 | public ICommand CmdCancelar 70 | { 71 | get { return (ICommand)GetValue(CmdCancelarProperty); } 72 | set 73 | { 74 | SetValue(CmdCancelarProperty, value); 75 | } 76 | } 77 | 78 | [Bindable(true)] 79 | public ICommand CmdImprimir 80 | { 81 | get { return (ICommand)GetValue(CmdImprimirProperty); } 82 | set 83 | { 84 | SetValue(CmdImprimirProperty, value); 85 | } 86 | } 87 | 88 | [Bindable(true)] 89 | public Visibility BtnInserirVisible 90 | { 91 | get { return (Visibility)GetValue(BtnInserirVisibleProperty); } 92 | set 93 | { 94 | SetValue(BtnInserirVisibleProperty, value); 95 | } 96 | } 97 | 98 | [Bindable(true)] 99 | public Visibility BtnEditarVisible 100 | { 101 | get { return (Visibility)GetValue(BtnEditarVisibleProperty); } 102 | set 103 | { 104 | SetValue(BtnEditarVisibleProperty, value); 105 | } 106 | } 107 | 108 | [Bindable(true)] 109 | public Visibility BtnExcluirVisible 110 | { 111 | get { return (Visibility)GetValue(BtnExcluirVisibleProperty); } 112 | set 113 | { 114 | SetValue(BtnExcluirVisibleProperty, value); 115 | } 116 | } 117 | 118 | [Bindable(true)] 119 | public Visibility BtnSalvarVisible 120 | { 121 | get { return (Visibility)GetValue(BtnSalvarVisibleProperty); } 122 | set 123 | { 124 | SetValue(BtnSalvarVisibleProperty, value); 125 | } 126 | } 127 | 128 | [Bindable(true)] 129 | public Visibility BtnPesquisarVisible 130 | { 131 | get { return (Visibility)GetValue(BtnPesquisarVisibleProperty); } 132 | set 133 | { 134 | SetValue(BtnPesquisarVisibleProperty, value); 135 | } 136 | } 137 | 138 | [Bindable(true)] 139 | public Visibility BtnCancelarVisible 140 | { 141 | get { return (Visibility)GetValue(BtnCancelarVisibleProperty); } 142 | set 143 | { 144 | SetValue(BtnCancelarVisibleProperty, value); 145 | } 146 | } 147 | 148 | [Bindable(true)] 149 | public Visibility BtnImprimirVisible 150 | { 151 | get { return (Visibility)GetValue(BtnImprimirVisibleProperty); } 152 | set 153 | { 154 | SetValue(BtnImprimirVisibleProperty, value); 155 | } 156 | } 157 | 158 | public static readonly DependencyProperty CmdInserirProperty = 159 | DependencyProperty.Register("CmdInserir", typeof(ICommand), typeof(TooolBarCadastro), new UIPropertyMetadata(null)); 160 | 161 | public static readonly DependencyProperty CmdEditarProperty = 162 | DependencyProperty.Register("CmdEditar", typeof(ICommand), typeof(TooolBarCadastro), new UIPropertyMetadata(null)); 163 | 164 | public static readonly DependencyProperty CmdExcluirProperty = 165 | DependencyProperty.Register("CmdExcluir", typeof(ICommand), typeof(TooolBarCadastro), new UIPropertyMetadata(null)); 166 | 167 | public static readonly DependencyProperty CmdSalvarProperty = 168 | DependencyProperty.Register("CmdSalvar", typeof(ICommand), typeof(TooolBarCadastro), new UIPropertyMetadata(null)); 169 | 170 | public static readonly DependencyProperty CmdCancelarProperty = 171 | DependencyProperty.Register("CmdCancelar", typeof(ICommand), typeof(TooolBarCadastro), new UIPropertyMetadata(null)); 172 | 173 | public static readonly DependencyProperty CmdPesquisarProperty = 174 | DependencyProperty.Register("CmdPesquisar", typeof(ICommand), typeof(TooolBarCadastro), new UIPropertyMetadata(null)); 175 | 176 | public static readonly DependencyProperty CmdImprimirProperty = 177 | DependencyProperty.Register("CmdImprimir", typeof(ICommand), typeof(TooolBarCadastro), new UIPropertyMetadata(null)); 178 | 179 | public static readonly DependencyProperty BtnInserirVisibleProperty = 180 | DependencyProperty.Register("BtnInserirVisible", typeof(Visibility), typeof(TooolBarCadastro), new UIPropertyMetadata(Visibility.Visible)); 181 | 182 | public static readonly DependencyProperty BtnEditarVisibleProperty = 183 | DependencyProperty.Register("BtnEditarVisible", typeof(Visibility), typeof(TooolBarCadastro), new UIPropertyMetadata(Visibility.Visible)); 184 | 185 | public static readonly DependencyProperty BtnExcluirVisibleProperty = 186 | DependencyProperty.Register("BtnExcluirVisible", typeof(Visibility), typeof(TooolBarCadastro), new UIPropertyMetadata(Visibility.Visible)); 187 | 188 | public static readonly DependencyProperty BtnSalvarVisibleProperty = 189 | DependencyProperty.Register("BtnSalvarVisible", typeof(Visibility), typeof(TooolBarCadastro), new UIPropertyMetadata(Visibility.Visible)); 190 | 191 | public static readonly DependencyProperty BtnCancelarVisibleProperty = 192 | DependencyProperty.Register("BtnCancelarVisible", typeof(Visibility), typeof(TooolBarCadastro), new UIPropertyMetadata(Visibility.Visible)); 193 | 194 | public static readonly DependencyProperty BtnPesquisarVisibleProperty = 195 | DependencyProperty.Register("BtnPesquisarVisible", typeof(Visibility), typeof(TooolBarCadastro), new UIPropertyMetadata(Visibility.Visible)); 196 | 197 | public static readonly DependencyProperty BtnImprimirVisibleProperty = 198 | DependencyProperty.Register("BtnImprimirVisible", typeof(Visibility), typeof(TooolBarCadastro), new UIPropertyMetadata(Visibility.Collapsed)); 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /WPFSimpleDemo/CustomControls/TooolBarCadastro.xaml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 22 | 37 | 50 | 64 | 77 | 90 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /WPFSimpleDemo/WPFSimpleDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D61388A4-688D-4A64-8B19-7A55C8E3FACA} 8 | WinExe 9 | Properties 10 | WPFSimpleDemo 11 | WPFSimpleDemo 12 | v4.6.1 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | true 17 | 18 | 19 | 20 | 21 | AnyCPU 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | 30 | 31 | AnyCPU 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE 36 | prompt 37 | 4 38 | 39 | 40 | 41 | ..\packages\Alphacloud.Common.ServiceLocator.Castle.1.3.0.0\lib\net45\Alphacloud.Common.ServiceLocator.Castle.dll 42 | True 43 | 44 | 45 | ..\packages\AutoMapper.5.1.1\lib\net45\AutoMapper.dll 46 | True 47 | 48 | 49 | ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll 50 | True 51 | 52 | 53 | ..\packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll 54 | True 55 | 56 | 57 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll 58 | True 59 | 60 | 61 | ..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll 62 | True 63 | 64 | 65 | ..\packages\FluentNHibernate.2.0.3.0\lib\net40\FluentNHibernate.dll 66 | True 67 | 68 | 69 | ..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll 70 | True 71 | 72 | 73 | ..\Libs\MvvmHelpers-4.04\Julmar.Core.dll 74 | 75 | 76 | ..\Libs\MvvmHelpers-4.04\Julmar.Wpf.Behaviors.dll 77 | 78 | 79 | ..\Libs\MvvmHelpers-4.04\JulMar.Wpf.Helpers.dll 80 | 81 | 82 | ..\packages\MaterialDesignColors.1.1.3\lib\net45\MaterialDesignColors.dll 83 | True 84 | 85 | 86 | ..\packages\MaterialDesignThemes.2.2.0.725\lib\net45\MaterialDesignThemes.Wpf.dll 87 | True 88 | 89 | 90 | ..\packages\EnterpriseLibrary.Common.6.0.1304.0\lib\NET45\Microsoft.Practices.EnterpriseLibrary.Common.dll 91 | True 92 | 93 | 94 | ..\packages\EnterpriseLibrary.Validation.6.0.1304.0\lib\NET45\Microsoft.Practices.EnterpriseLibrary.Validation.dll 95 | True 96 | 97 | 98 | ..\packages\EnterpriseLibrary.Validation.Integration.WPF.6.0.1304.0\lib\NET45\Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WPF.dll 99 | True 100 | 101 | 102 | ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll 103 | True 104 | 105 | 106 | ..\packages\NHibernate.4.0.0.4000\lib\net40\NHibernate.dll 107 | True 108 | 109 | 110 | 111 | 112 | 113 | ..\packages\System.Data.SQLite.Core.1.0.103\lib\net46\System.Data.SQLite.dll 114 | True 115 | 116 | 117 | ..\packages\System.Data.SQLite.EF6.1.0.103\lib\net46\System.Data.SQLite.EF6.dll 118 | True 119 | 120 | 121 | ..\packages\System.Data.SQLite.Linq.1.0.103\lib\net46\System.Data.SQLite.Linq.dll 122 | True 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 4.0 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | MSBuild:Compile 140 | Designer 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | MSBuild:Compile 161 | Designer 162 | 163 | 164 | MSBuild:Compile 165 | Designer 166 | 167 | 168 | App.xaml 169 | Code 170 | 171 | 172 | 173 | TooolBarCadastro.xaml 174 | 175 | 176 | MainWindow.xaml 177 | Code 178 | 179 | 180 | 181 | 182 | Code 183 | 184 | 185 | True 186 | True 187 | Resources.resx 188 | 189 | 190 | True 191 | Settings.settings 192 | True 193 | 194 | 195 | ResXFileCodeGenerator 196 | Resources.Designer.cs 197 | 198 | 199 | 200 | SettingsSingleFileGenerator 201 | Settings.Designer.cs 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 214 | 215 | 216 | 217 | 224 | -------------------------------------------------------------------------------- /Libs/MvvmHelpers-4.04/Julmar.Wpf.Behaviors.XML: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Julmar.Wpf.Behaviors 5 | 6 | 7 | 8 | 9 | Drag Adorner - this was taken from a sample posted by Bea Stollnitz 10 | See http://www.beacosta.com/blog/?p=53 for the original article. 11 | 12 | 13 | 14 | 15 | Constructor for the drag adorner 16 | 17 | Tag data 18 | Template for visual 19 | Element we are adorning 20 | Adorner layer to insert into 21 | 22 | 23 | 24 | This changes the position of the adorner. 25 | 26 | 27 | 28 | 29 | 30 | 31 | Implements any custom measuring behavior for the adorner. 32 | 33 | 34 | A object representing the amount of layout space needed by the adorner. 35 | 36 | A size to constrain the adorner to. 37 | 38 | 39 | 40 | When overridden in a derived class, positions child elements and determines a size for a derived class. 41 | 42 | 43 | The actual size used. 44 | 45 | The final area within the parent that this element should use to arrange itself and its children. 46 | 47 | 48 | 49 | Overrides , and returns a child at the specified index from a collection of child elements. 50 | 51 | 52 | The requested child element. This should not return null; if the provided index is out of range, an exception is thrown. 53 | 54 | The zero-based index of the requested child element in the collection. 55 | 56 | 57 | 58 | Returns a for the adorner, based on the transform that is currently applied to the adorned element. 59 | 60 | 61 | A transform to apply to the adorner. 62 | 63 | The transform that is currently applied to the adorned element. 64 | 65 | 66 | 67 | This removes the item from the adorner layer 68 | 69 | 70 | 71 | 72 | Gets the number of visual child elements within this element. 73 | 74 | 75 | The number of visual child elements for this element. 76 | 77 | 78 | 79 | 80 | This changes the window's theme to the given theme URI. 81 | 82 | 83 | 84 | 85 | Theme URI to apply to the application 86 | 87 | 88 | 89 | 90 | Invokes the action. 91 | 92 | The parameter to the action. If the Action does not require a parameter, the parameter may be set to a null reference. 93 | 94 | 95 | 96 | Raises the ThemeChanged event 97 | 98 | 99 | 100 | 101 | Theme URI to apply to the application. 102 | 103 | 104 | 105 | 106 | This event is raised when the theme is changed. 107 | 108 | 109 | 110 | 111 | This behavior associates a watermark onto a TextBox indicating what the user should 112 | provide as input. 113 | 114 | 115 | 116 | 117 | The watermark text 118 | 119 | 120 | 121 | 122 | Readonly property used to style the TextBox when the watermark is present 123 | 124 | 125 | 126 | 127 | This readonly property is applied to the TextBox and indicates whether the watermark 128 | is currently being displayed. It allows a style to change the visual appearanve of the 129 | TextBox. 130 | 131 | 132 | 133 | 134 | Retrieves the current watermarked state of the TextBox. 135 | 136 | 137 | 138 | 139 | 140 | 141 | Called after the behavior is attached to an AssociatedObject. 142 | 143 | 144 | Override this to hook up functionality to the AssociatedObject. 145 | 146 | 147 | 148 | 149 | This method is called when the text for the TextBox is changed. 150 | 151 | 152 | 153 | 154 | 155 | 156 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 157 | 158 | 159 | Override this to unhook functionality from the AssociatedObject. 160 | 161 | 162 | 163 | 164 | This method is called when the textbox gains focus. It removes the watermark. 165 | 166 | 167 | 168 | 169 | 170 | 171 | This method is called when focus is lost from the TextBox. It puts the watermark 172 | into place if no text is in the textbox. 173 | 174 | 175 | 176 | 177 | 178 | 179 | This method is used to change the text. 180 | 181 | New string to assign to TextBox 182 | 183 | 184 | 185 | Retrieves the current watermarked state of the TextBox. 186 | 187 | 188 | 189 | 190 | The watermark text 191 | 192 | 193 | 194 | 195 | ItemsControlDragDropBehavior can be used to add automatic Drag/Drop support 196 | to any ItemsControl based element. 197 | 198 | 199 | This was originally taken from a sample posted by Bea Stollnitz 200 | See http://www.beacosta.com/blog/?p=53 for the original article. 201 | I have also borrowed elements from http://code.google.com/p/gong-wpf-dragdrop/ 202 | which was an extension of the above codebase. 203 | 204 | 205 | 206 | 207 | Constructor 208 | 209 | 210 | 211 | 212 | Called after the behavior is attached to an AssociatedObject. 213 | 214 | 215 | Override this to hook up functionality to the AssociatedObject. 216 | 217 | 218 | 219 | 220 | Starts the drag/drop operation. 221 | 222 | 223 | 224 | 225 | 226 | 227 | Display the drag indicator 228 | 229 | 230 | 231 | 232 | 233 | 234 | Stops the drag/drop operation 235 | 236 | 237 | 238 | 239 | 240 | 241 | New drop target identified 242 | 243 | 244 | 245 | 246 | 247 | 248 | New drop target being dragged over 249 | 250 | 251 | 252 | 253 | 254 | 255 | Drop target has left control airspace 256 | 257 | 258 | 259 | 260 | 261 | 262 | Query to continue dragging operation 263 | 264 | 265 | 266 | 267 | 268 | 269 | Drop started 270 | 271 | 272 | 273 | 274 | 275 | 276 | This starts the drag operation from the given ItemsControl 277 | 278 | 279 | 280 | 281 | 282 | Returns the drop effects allowed 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | This scrolls the items control when we hit a boundary 291 | 292 | 293 | 294 | 295 | 296 | 297 | Determine the proper insertion index 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | Resets the drag/drop operation 306 | 307 | 308 | 309 | 310 | Initialize the drag adorner -- this is the DataTemplate instantiation of the item 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | Update the position of the drag adorner 319 | 320 | 321 | 322 | 323 | 324 | Initialize the insertion point marker 325 | 326 | 327 | 328 | 329 | 330 | 331 | Update the position of the insertion point marker 332 | 333 | 334 | 335 | 336 | 337 | 338 | Remove all the adorners 339 | 340 | 341 | 342 | 343 | Key used for drag/drop operations 344 | 345 | 346 | 347 | 348 | Data template to represent drag items 349 | 350 | 351 | 352 | 353 | True to only allow "Self" as drop target 354 | 355 | 356 | 357 | 358 | This event is raised when a drag/drop operation starts 359 | 360 | 361 | 362 | 363 | This event is raised when a target is identified 364 | 365 | 366 | 367 | 368 | This event is raised when a drop is initiated 369 | 370 | 371 | 372 | 373 | This behavior changes the Text for the associated TextBlock 374 | to the current row index of the DataGridRow it is bound to. 375 | 376 | 377 | 378 | 379 | Internal target property used to track current item of DataGridRow. 380 | 381 | 382 | 383 | 384 | DataGridRow this behavior uses to determine the proper row index. 385 | 386 | 387 | 388 | 389 | This is called when the DataGridRow property is changed. It generally means 390 | a new row has been added into the grid and we need to set the initial row 391 | value for it. We won't see a CollectionChange for this item - the event isn't 392 | hooked up yet. 393 | 394 | 395 | 396 | 397 | 398 | 399 | Detaches object from row - called when being unloaded. 400 | 401 | 402 | 403 | 404 | 405 | This is called when the item associated with the DG row changes; this possibly 406 | requires a change in the index. 407 | 408 | 409 | 410 | 411 | 412 | 413 | This is used to reset the header on the NewItemPlaceholder. 414 | 415 | 416 | 417 | 418 | 419 | 420 | This is called when the ItemsSource collection changes - i.e. it is sorted, 421 | items are removed, inserted, etc. It updates the *existing* row numbers. 422 | 423 | 424 | 425 | 426 | 427 | 428 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 429 | 430 | 431 | 432 | 433 | DataGridRow this behavior uses to determine the proper row index. 434 | 435 | 436 | 437 | 438 | This class is passed around from drop source to target 439 | 440 | 441 | 442 | 443 | This behavior synchronizes a collection with the Multiple Selection of a ListBox or MultiSelector. 444 | 445 | 446 | 447 | 448 | Dependency Property to manage collection 449 | 450 | 451 | 452 | 453 | Called after the behavior is attached to an AssociatedObject. 454 | 455 | 456 | Override this to hook up functionality to the AssociatedObject. 457 | 458 | 459 | 460 | 461 | Processes the selection change event from the ListBox/MultiSelector. 462 | 463 | 464 | 465 | 466 | 467 | 468 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 469 | 470 | 471 | Override this to unhook functionality from the AssociatedObject. 472 | 473 | 474 | 475 | 476 | Collection to synchronize 477 | 478 | 479 | 480 | 481 | WPF attached behavior which attaches the NumericTextBoxBehavior to any TextBox. 482 | 483 | 484 | 485 | 486 | Minimum amount of distance mouse must be "dragged" before we begin changing 487 | the numeric value. 488 | 489 | 490 | 491 | 492 | This property allows the behavior to be used as a traditional 493 | attached property behavior. 494 | 495 | 496 | 497 | 498 | Returns whether NumericTextBoxBehavior is enabled via attached property 499 | 500 | 501 | True/FalseB 502 | 503 | 504 | 505 | Adds NumericTextBoxBehavior to TextBox 506 | 507 | TextBox to apply 508 | True/False 509 | 510 | 511 | 512 | AllowMouseDrag Dependency Property 513 | 514 | 515 | 516 | 517 | This attaches the property handlers - PreviewKeyDown, Clipboard support and our adorner. 518 | 519 | 520 | 521 | 522 | This adds the adorner. 523 | 524 | 525 | 526 | 527 | This removes all our handlers. 528 | 529 | 530 | 531 | 532 | This method handles paste and drag/drop events onto the TextBox. It restricts the character 533 | set to numerics and ensures we have consistent behavior. 534 | 535 | TextBox sender 536 | EventArgs 537 | 538 | 539 | 540 | This checks the PreviewKeyDown on the TextBox and constrains it to a numeric value. 541 | 542 | 543 | 544 | 545 | 546 | 547 | Gets or sets the AllowMouseDrag property. When set to "True", the NumericTextBoxBehavior will allow 548 | Mouse "drags" to adjust the value - similar to the Blend text boxes. 549 | 550 | 551 | 552 | 553 | This visual adorner is used to provide mouse cursor + numeric up/down drag support 554 | on top of an existing TextBox. It provides scroll wheel + left/right dragging 555 | 556 | 557 | 558 | 559 | Constructor 560 | 561 | 562 | 563 | 564 | 565 | This is called as the cursor moves to change the visual representation on the screen. 566 | We display the W/E cursor or the IBeam. 567 | 568 | 569 | 570 | 571 | 572 | Called to render the visual - we place a transparent (hit-testable) rectangle on top 573 | of the text box. 574 | 575 | 576 | 577 | 578 | 579 | Left button down 580 | 581 | 582 | 583 | 584 | 585 | Mouse movement 586 | 587 | 588 | 589 | 590 | 591 | Left button up 592 | 593 | 594 | 595 | 596 | 597 | Mouse wheel changes 598 | 599 | 600 | 601 | 602 | 603 | Detection for double-click support 604 | 605 | 606 | 607 | 608 | 609 | This is used to remove the adorner 610 | 611 | 612 | 613 | 614 | This is used to change the focus to the text box and adjust the cursor 615 | 616 | 617 | 618 | 619 | 620 | This is used to adjust the numeric value in the TextBox. 621 | 622 | 623 | 624 | 625 | 626 | 627 | This behavior tracks two ScrollViewer based controls and keeps their 628 | Horizontal and Vertical positions synchronized. 629 | 630 | 631 | 632 | 633 | Called after the behavior is attached to an AssociatedObject. 634 | 635 | 636 | Override this to hook up functionality to the AssociatedObject. 637 | 638 | 639 | 640 | 641 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 642 | 643 | 644 | Override this to unhook functionality from the AssociatedObject. 645 | 646 | 647 | 648 | 649 | This dependency property holds the horizontal adjustment factor when two ScrollViewer instances do not have the 650 | same size or elements. 651 | 652 | 653 | 654 | 655 | This dependency property holds the vertical adjustment factor when two ScrollViewer instances do not have the 656 | same size or elements. 657 | 658 | 659 | 660 | 661 | This holds the target to synchronize to. 662 | 663 | 664 | 665 | 666 | This method is called when the target property is changed. 667 | 668 | Dependency object 669 | EventArgs 670 | 671 | 672 | 673 | This handles the synchronization when the source list is scrolled. 674 | 675 | 676 | 677 | 678 | 679 | 680 | This handles the synchronization when the target list is scrolled. 681 | 682 | 683 | 684 | 685 | 686 | 687 | This is the command scroll adjustment code which synchronizes two ScrollViewer instances. 688 | 689 | ScrollViewer to adjust 690 | Change in the source 691 | Horizontal adjustment 692 | Vertical adjustment 693 | 694 | 695 | 696 | The horizontal adjustment to apply between source and target. 697 | 698 | 699 | 700 | 701 | The vertical adjustment to apply between source and target. 702 | 703 | 704 | 705 | 706 | The target ScrollViewer to synchronize to 707 | 708 | 709 | 710 | 711 | This Blend behavior provides positional translation for UIElements through a 712 | RenderTransform using Drag/Drop semantics. 713 | 714 | 715 | 716 | 717 | This property allows the behavior to be used as a traditional 718 | attached property behavior. 719 | 720 | 721 | 722 | 723 | Returns whether DragPositionBehavior is enabled via attached property 724 | 725 | Element 726 | True/False 727 | 728 | 729 | 730 | Adds DragPositionBehavior to an element 731 | 732 | Element to apply 733 | True/False 734 | 735 | 736 | 737 | This is called when the IsEnabled property has changed. 738 | 739 | 740 | 741 | 742 | 743 | 744 | Called after the behavior is attached to an AssociatedObject. 745 | 746 | 747 | Override this to hook up functionality to the AssociatedObject. 748 | 749 | 750 | 751 | 752 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 753 | 754 | 755 | Override this to unhook functionality from the AssociatedObject. 756 | 757 | 758 | 759 | 760 | Handles the MouseDown event 761 | 762 | UIElement 763 | Mouse eventargs 764 | 765 | 766 | 767 | This class encapsulates the drag data + logic for a given element. 768 | It saves memory space as it is only allocated while the object is 769 | being dragged around. 770 | 771 | 772 | 773 | 774 | This behavior selects all text in a TextBox when it gets focus 775 | 776 | 777 | 778 | 779 | Called after the behavior is attached to an AssociatedObject. 780 | 781 | 782 | Override this to hook up functionality to the AssociatedObject. 783 | 784 | 785 | 786 | 787 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 788 | 789 | 790 | Override this to unhook functionality from the AssociatedObject. 791 | 792 | 793 | 794 | 795 | This selects the text in the TextBox. 796 | 797 | 798 | 799 | 800 | 801 | 802 | Insertion Adorner - this was taken from a sample posted by Bea Stollnitz 803 | See http://www.beacosta.com/blog/?p=53 for the original article. 804 | 805 | 806 | 807 | 808 | Constructor 809 | 810 | Horizontal vs. vertical separator 811 | First half of items control 812 | Element being adorner 813 | Layer 814 | Parent container to constrain drawing 815 | 816 | 817 | 818 | Calculates the top and end points 819 | 820 | 821 | 822 | 823 | 824 | 825 | Ensures our point does not escape the parent boundaries. 826 | 827 | 828 | 829 | 830 | 831 | Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 832 | 833 | 834 | 835 | 836 | Displays a ToolTip next to the ScrollBar thumb while it is being dragged. 837 | The original idea and code was taken from an MSDN sample - see http://code.msdn.microsoft.com/getwpfcode/Release/ProjectReleases.aspx?ReleaseId=1445 838 | for the original source code and project. 839 | 840 | 841 | 842 | 843 | Specifies a ContentTemplate for a ToolTip that will appear next to the ScrollBar while dragging the thumb. 844 | 845 | 846 | 847 | 848 | Holds the ToolTip when it is being used. 849 | 850 | 851 | 852 | 853 | Called after the behavior is attached to an AssociatedObject. 854 | 855 | 856 | Override this to hook up functionality to the AssociatedObject. 857 | 858 | 859 | 860 | 861 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 862 | 863 | 864 | Override this to unhook functionality from the AssociatedObject. 865 | 866 | 867 | 868 | 869 | Gets/Sets the vertical scrolling preview template 870 | 871 | 872 | 873 | 874 | Provides data that should be useful to templates displaying 875 | a preview. 876 | 877 | 878 | 879 | 880 | Updates Offset, Viewport, and Extent. 881 | 882 | 883 | 884 | 885 | Raises the PropertyChanged event. 886 | 887 | The name of the property. 888 | 889 | 890 | 891 | The Scrollbar's current value 892 | 893 | 894 | 895 | 896 | The ScrollBar's offset. 897 | 898 | 899 | 900 | 901 | The size of the current viewport. 902 | 903 | 904 | 905 | 906 | The entire scrollable range. 907 | 908 | 909 | 910 | 911 | Notifies listeners of changes to properties on this object. 912 | 913 | 914 | 915 | 916 | EventArgs for our drag/drop 917 | 918 | 919 | 920 | 921 | Constructor 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | Source where the item is currently located 931 | 932 | 933 | 934 | 935 | Destination where item is being dropped (may be null) 936 | 937 | 938 | 939 | 940 | Object being copied or moved 941 | 942 | 943 | 944 | 945 | Position we are dropping item onto 946 | 947 | 948 | 949 | 950 | Set to true to disallow drag/drop operation 951 | 952 | 953 | 954 | 955 | Initially holds allowed effects, can be modified to restrict 956 | operations 957 | 958 | 959 | 960 | 961 | This adorner draws the sorting arrow onto the ListView column 962 | header and provides the visual feedback for the sorting direction. 963 | 964 | 965 | 966 | 967 | The color of the arrow 968 | 969 | 970 | 971 | 972 | Constructor 973 | 974 | Element (ColumnHeader) to adorn 975 | 976 | 977 | 978 | Pen used to draw geometry (none) 979 | 980 | 981 | 982 | 983 | The geometry for the up arrow 984 | 985 | 986 | 987 | 988 | The geometry for the down arrow 989 | 990 | 991 | 992 | 993 | When overridden in a derived class, participates in rendering operations that are directed by the layout system. The rendering instructions for this element are not used directly when this method is invoked, and are instead preserved for later asynchronous use by layout and drawing. 994 | 995 | The drawing instructions for a specific element. This context is provided to the layout system. 996 | 997 | 998 | 999 | The direction to draw the arrow (up vs. down) 1000 | 1001 | 1002 | 1003 | 1004 | The color of the arrow 1005 | 1006 | 1007 | 1008 | 1009 | Behavior to provide automatic sorting of a ListView. 1010 | 1011 | 1012 | 1013 | 1014 | Initial column index 1015 | 1016 | 1017 | 1018 | 1019 | Sort direction 1020 | 1021 | 1022 | 1023 | 1024 | The color of the arrow 1025 | 1026 | 1027 | 1028 | 1029 | Called after the behavior is attached to an AssociatedObject. 1030 | 1031 | 1032 | Override this to hook up functionality to the AssociatedObject. 1033 | 1034 | 1035 | 1036 | 1037 | Called when the ListView has completely loaded. 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 1045 | 1046 | 1047 | Override this to unhook functionality from the AssociatedObject. 1048 | 1049 | 1050 | 1051 | 1052 | This is called when a Button.Click event occurs inside 1053 | the ListView. Here we filter to the column headers and 1054 | then provide the sorting when that happens. 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | This method provides the actual sorting behavior. 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | Initial sorting column 1068 | 1069 | 1070 | 1071 | 1072 | Sort direction 1073 | 1074 | 1075 | 1076 | 1077 | The color of the arrow 1078 | 1079 | 1080 | 1081 | 1082 | This behavior allows a ViewModel to monitor and control the scrolling position of any ScrollViewer or 1083 | control with a ScrollViewer in the template. It can also be used to synchronize two scrolling items 1084 | against a single property in a ViewModel. 1085 | 1086 | 1087 | 1088 | 1089 | Vertical offset of the scroll viewer 1090 | 1091 | 1092 | 1093 | 1094 | Vertical height of the scroll viewer 1095 | 1096 | 1097 | 1098 | 1099 | Horizontal width of the scroll viewer 1100 | 1101 | 1102 | 1103 | 1104 | Horizontal offset of the scroll viewer 1105 | 1106 | 1107 | 1108 | 1109 | Called after the behavior is attached to an AssociatedObject. 1110 | 1111 | 1112 | Override this to hook up functionality to the AssociatedObject. 1113 | 1114 | 1115 | 1116 | 1117 | Attaches to the scrollviewer. 1118 | 1119 | 1120 | 1121 | 1122 | This is called when the associated object's size changes. 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | Called when the scrollviewer changes the size 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | This method is called when the scroll viewer is scrolled. 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 1144 | 1145 | 1146 | Override this to unhook functionality from the AssociatedObject. 1147 | 1148 | 1149 | 1150 | 1151 | This method is called when the VerticalOffset property is changed. 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | This method is called when HorizontalOffset property is changed. 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | The vertical offset 1166 | 1167 | 1168 | 1169 | 1170 | The vertical height of the scrollviewer 1171 | 1172 | 1173 | 1174 | 1175 | The horizontal width of the scrollviewer 1176 | 1177 | 1178 | 1179 | 1180 | The horizontal offset 1181 | 1182 | 1183 | 1184 | 1185 | This action sets focus to the associated element. 1186 | 1187 | 1188 | 1189 | 1190 | Dependency Property backing the Target property. 1191 | 1192 | 1193 | 1194 | 1195 | Invokes the action. 1196 | 1197 | The parameter to the action. If the Action does not require a parameter, the parameter may be set to a null reference. 1198 | 1199 | 1200 | 1201 | This property allows you to set the focus target independant of where this 1202 | action is applied - so you can apply the trigger/action to the Window and then 1203 | push focus to a child element as an example. 1204 | 1205 | 1206 | 1207 | 1208 | This action applies a specific media effect to the element. It is used as a Blend 1209 | Action and will apply/remove an effect based on the Effect property (leave it null 1210 | to clear any effect on the target element). 1211 | 1212 | 1213 | 1214 | 1215 | Effect property 1216 | 1217 | 1218 | 1219 | 1220 | Called to apply the effect when the trigger is active. 1221 | 1222 | Can pass in specific effect if desired, overrides Property 1223 | 1224 | 1225 | 1226 | The effect to apply 1227 | 1228 | 1229 | 1230 | 1231 | This is a Blend trigger that binds to a IViewModelTrigger and invokes actions when it 1232 | is raised by the ViewModel. This allows the VM to trigger behaviors in the View easily. 1233 | 1234 | 1235 | 1236 | 1237 | The DependencyProperty used to hold the IViewModelTrigger. 1238 | 1239 | 1240 | 1241 | 1242 | Change handler for IViewModelTrigger. 1243 | 1244 | VMTrigger object 1245 | EventArgs 1246 | 1247 | 1248 | 1249 | This is called when the trigger occurs. 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | IViewModelTrigger to hook into. 1256 | 1257 | 1258 | 1259 | 1260 | Displays a ToolTip next to the ScrollBar thumb while it is being dragged. 1261 | This code was taken from an MSDN sample - 1262 | see http://code.msdn.microsoft.com/getwpfcode/Release/ProjectReleases.aspx?ReleaseId=1445 1263 | for the original source code and project. 1264 | 1265 | 1266 | 1267 | 1268 | Allows for specifying a ContentTemplate for a ToolTip that will appear next to the 1269 | vertical ScrollBar while dragging the thumb. 1270 | 1271 | 1272 | 1273 | 1274 | Allows for specifying a ContentTemplate for a ToolTip that will appear next to the 1275 | horizontal ScrollBar while dragging the thumb. 1276 | 1277 | 1278 | 1279 | 1280 | Called after the behavior is attached to an AssociatedObject. 1281 | 1282 | 1283 | Override this to hook up functionality to the AssociatedObject. 1284 | 1285 | 1286 | 1287 | 1288 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 1289 | 1290 | 1291 | Override this to unhook functionality from the AssociatedObject. 1292 | 1293 | 1294 | 1295 | 1296 | Retrieves the vertical scrolling preview template 1297 | 1298 | 1299 | 1300 | 1301 | Gets the horizontal scrolling preview template 1302 | 1303 | 1304 | 1305 | 1306 | Provides data that should be useful to templates displaying 1307 | a preview. 1308 | 1309 | 1310 | 1311 | 1312 | Updates Offset, Viewport, and Extent. 1313 | 1314 | 1315 | 1316 | 1317 | Updates FirstItem and LastItem based on the 1318 | Offset and Viewport properties. 1319 | 1320 | The ItemsControl that contains the data items. 1321 | True for vertical scrollbar 1322 | 1323 | 1324 | 1325 | Raises the PropertyChanged event. 1326 | 1327 | The name of the property. 1328 | 1329 | 1330 | 1331 | The Scrollbar's current value 1332 | 1333 | 1334 | 1335 | 1336 | The ScrollBar's offset. 1337 | 1338 | 1339 | 1340 | 1341 | The size of the current viewport. 1342 | 1343 | 1344 | 1345 | 1346 | The entire scrollable range. 1347 | 1348 | 1349 | 1350 | 1351 | The first visible item in the viewport. 1352 | 1353 | 1354 | 1355 | 1356 | The last visible item in the viewport. 1357 | 1358 | 1359 | 1360 | 1361 | Notifies listeners of changes to properties on this object. 1362 | 1363 | 1364 | 1365 | 1366 | This behavior allows the designer to close a dialog using a true/false DialogResult through a button. 1367 | This is already supported if the IsCancel property is true, but the IsDefault does not auto-dismiss the dialog 1368 | without some code behind. This aleviates that requirement for the very simple dialogs that are completely VM driven. 1369 | 1370 | 1371 | 1372 | 1373 | DialogResult dependency property 1374 | 1375 | 1376 | 1377 | 1378 | Called after the behavior is attached to an AssociatedObject. 1379 | 1380 | 1381 | Override this to hook up functionality to the AssociatedObject. 1382 | 1383 | 1384 | 1385 | 1386 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 1387 | 1388 | 1389 | Override this to unhook functionality from the AssociatedObject. 1390 | 1391 | 1392 | 1393 | 1394 | This dismisses the associated window 1395 | 1396 | 1397 | 1398 | 1399 | 1400 | 1401 | Dismiss dialog result value - this is assigned to the window.DialogResult to close the window. 1402 | 1403 | 1404 | 1405 | 1406 | This is an attached behavior for Blend 3 that allows a Event -> Command trigger 1407 | 1408 | 1409 | 1410 | 1411 | Command Property Dependency Property 1412 | 1413 | 1414 | 1415 | 1416 | Parameter for the ICommand 1417 | 1418 | 1419 | 1420 | 1421 | Event Dependency Property 1422 | 1423 | 1424 | 1425 | 1426 | This is called when the command parameter changes -- this can 1427 | happen if it is databound. 1428 | 1429 | DependencyObject 1430 | Change 1431 | 1432 | 1433 | 1434 | Called after the behavior is attached to an AssociatedObject. 1435 | 1436 | 1437 | Override this to hook up functionality to the AssociatedObject. 1438 | 1439 | 1440 | 1441 | 1442 | Hooks the event maps 1443 | 1444 | 1445 | 1446 | 1447 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 1448 | 1449 | 1450 | Override this to unhook functionality from the AssociatedObject. 1451 | 1452 | 1453 | 1454 | 1455 | Defines the method that determines whether the command can execute in its current state. 1456 | 1457 | 1458 | true if this command can be executed; otherwise, false. 1459 | 1460 | Data used by the command. If the command does not require data to be passed, this object can be set to null. 1461 | 1462 | 1463 | 1464 | Defines the method to be called when the command is invoked. 1465 | 1466 | Data used by the command. If the command does not require data to be passed, this object can be set to null. 1467 | 1468 | 1469 | 1470 | Gets or sets the Event property. 1471 | 1472 | 1473 | 1474 | 1475 | Gets or sets the Command property. 1476 | 1477 | 1478 | 1479 | 1480 | Gets or sets the CommandParameter property. 1481 | 1482 | 1483 | 1484 | 1485 | Occurs when changes occur that affect whether or not the command should execute. 1486 | 1487 | 1488 | 1489 | 1490 | This is a Blend/VS.NET behavior which drives a Click event to 1491 | some interactive action 1492 | 1493 | 1494 | 1495 | 1496 | The DependencyProperty for the ClickMode property. 1497 | 1498 | 1499 | 1500 | 1501 | Called after the behavior is attached to an AssociatedObject. 1502 | 1503 | 1504 | Override this to hook up functionality to the AssociatedObject. 1505 | 1506 | 1507 | 1508 | 1509 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 1510 | 1511 | 1512 | Override this to unhook functionality from the AssociatedObject. 1513 | 1514 | 1515 | 1516 | 1517 | Mark that a ButtonDown occurred. 1518 | 1519 | UIElement 1520 | EventArgs 1521 | 1522 | 1523 | 1524 | Mark that a ButtonDown occurred. 1525 | 1526 | UIElement 1527 | EventArgs 1528 | 1529 | 1530 | 1531 | Mark that a ButtonDown occurred. 1532 | 1533 | UIElement 1534 | EventArgs 1535 | 1536 | 1537 | 1538 | ClickMode specify when the Click event should fire 1539 | 1540 | 1541 | 1542 | 1543 | This trigger action binds a command/command parameter for MVVM usage with 1544 | a Blend based trigger. This is used in place of the one in the Blend samples - 1545 | it has a problem in it as of the current (first) release. Once it is fixed, this 1546 | command can go away. 1547 | 1548 | 1549 | 1550 | 1551 | ICommand to execute 1552 | 1553 | 1554 | 1555 | 1556 | Command parameter to pass to command execution 1557 | 1558 | 1559 | 1560 | 1561 | This is called to execute the command when the trigger conditions are satisified. 1562 | 1563 | parameter (not used) 1564 | 1565 | 1566 | 1567 | Command to execute 1568 | 1569 | 1570 | 1571 | 1572 | Command parameter 1573 | 1574 | 1575 | 1576 | 1577 | Drag Utilities - this was taken from a sample posted by Bea Stollnitz 1578 | See http://www.beacosta.com/blog/?p=53 for the original article. 1579 | 1580 | 1581 | 1582 | 1583 | This is a Blend/VS.NET behavior which drives a DoubleClick event to 1584 | some interactive action 1585 | 1586 | 1587 | 1588 | 1589 | Called after the behavior is attached to an AssociatedObject. 1590 | 1591 | 1592 | Override this to hook up functionality to the AssociatedObject. 1593 | 1594 | 1595 | 1596 | 1597 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 1598 | 1599 | 1600 | Override this to unhook functionality from the AssociatedObject. 1601 | 1602 | 1603 | 1604 | 1605 | This handles the UIElement.LeftButtonDown event to test for a double-click event. 1606 | 1607 | UIElement 1608 | EventArgs 1609 | 1610 | 1611 | 1612 | This triggers off a binding expression. It allows a designer to run a set of actions using a MVVM property as the trigger. 1613 | As a side effect it also allows the Value to be data bound so you can compare two ViewModel properties for equality and then run 1614 | a set of actions when the condition is matched. 1615 | 1616 | 1617 | 1618 | 1619 | Value to test against 1620 | 1621 | 1622 | 1623 | 1624 | This is called when the DP backed by the binding changes 1625 | 1626 | 1627 | 1628 | 1629 | 1630 | 1631 | This compares a changed value 1632 | 1633 | 1634 | 1635 | 1636 | Binding declaration of the conditional 1637 | 1638 | 1639 | 1640 | 1641 | Gets or sets the Value property. 1642 | 1643 | 1644 | 1645 | 1646 | WPF attached behavior which attaches a regular expression to a TextBox. 1647 | 1648 | 1649 | 1650 | 1651 | This property serves a dual purpose. First, it allows the behavior to be used as a traditional 1652 | attached property behavior - without use of the Blend tool. Second, it acts as a local property 1653 | to store the expression. 1654 | 1655 | 1656 | 1657 | 1658 | Returns whether MaskedTextBoxBehavior is enabled via attached property 1659 | 1660 | 1661 | Regular Expression Mask 1662 | 1663 | 1664 | 1665 | Adds MaskedTextBoxBehavior to TextBox 1666 | 1667 | TextBox to apply 1668 | True/False 1669 | 1670 | 1671 | 1672 | This associates a new MaskedTextBoxBehavior onto a TextBox using the applied mask. 1673 | 1674 | 1675 | 1676 | 1677 | 1678 | 1679 | This attaches the property handlers - PreviewKeyDown and Clipboard support. 1680 | 1681 | 1682 | 1683 | 1684 | This removes all our handlers. 1685 | 1686 | 1687 | 1688 | 1689 | This is called to process text (character) input 1690 | 1691 | 1692 | 1693 | 1694 | 1695 | 1696 | This method handles paste and drag/drop events onto the TextBox. It restricts the character 1697 | set to numerics and ensures we have consistent behavior. 1698 | 1699 | TextBox sender 1700 | EventArgs 1701 | 1702 | 1703 | 1704 | This checks the PreviewKeyDown on the TextBox to check for the SPACE 1705 | character which is not considered a TextInput element. 1706 | 1707 | 1708 | 1709 | 1710 | 1711 | 1712 | This returns the next text value if the pending event is processed. 1713 | 1714 | Text to add to the TextBox 1715 | String 1716 | 1717 | 1718 | 1719 | This method is used to test the string input. 1720 | 1721 | 1722 | 1723 | 1724 | 1725 | 1726 | Mask to use for the regular expression. 1727 | 1728 | 1729 | 1730 | 1731 | This class provides deferred scrolling capability to a normal scrollbar - the same 1732 | way a ScrollViewer can have deferred scrolling. 1733 | 1734 | 1735 | 1736 | 1737 | The Value property represents the current position of the ScrollBar. Changes made to this 1738 | value will be propogated to the thumb value. 1739 | 1740 | 1741 | 1742 | 1743 | This method is called when the value is changed. 1744 | 1745 | 1746 | 1747 | 1748 | 1749 | 1750 | This method adjusts the thumb position to the currently tracked value position. 1751 | 1752 | Current value 1753 | New value 1754 | 1755 | 1756 | 1757 | This attaches the behavior to the ScrollBar. 1758 | 1759 | 1760 | 1761 | 1762 | This detaches the behavior from the ScrollBar. 1763 | 1764 | 1765 | 1766 | 1767 | This is called when ScrollBar changes the thumb position. 1768 | 1769 | 1770 | 1771 | 1772 | 1773 | 1774 | The current position of the ScrollBar. 1775 | 1776 | 1777 | 1778 | 1779 | This class enables a DataGrid to drag/drop to reorder rows. 1780 | 1781 | 1782 | 1783 | 1784 | Row drag target 1785 | 1786 | 1787 | 1788 | 1789 | Called after the behavior is attached to an AssociatedObject. 1790 | 1791 | 1792 | Override this to hook up functionality to the AssociatedObject. 1793 | 1794 | 1795 | 1796 | 1797 | This is used to drop the target 1798 | 1799 | 1800 | 1801 | 1802 | 1803 | 1804 | This is used to verify the location of the drop. 1805 | 1806 | 1807 | 1808 | 1809 | 1810 | 1811 | This handler monitors the mouse movement and initiates the drag/drop operation. 1812 | 1813 | 1814 | 1815 | 1816 | 1817 | 1818 | Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 1819 | 1820 | 1821 | Override this to unhook functionality from the AssociatedObject. 1822 | 1823 | 1824 | 1825 | 1826 | This is invoked when the drop is started (prior to moving the item) 1827 | 1828 | 1829 | 1830 | 1831 | This is invoked after the item has been moved. 1832 | 1833 | 1834 | 1835 | 1836 | The EventArgs parameter passed on the drop 1837 | 1838 | 1839 | 1840 | 1841 | EventArgs passed with DropStarted and DropFinished 1842 | 1843 | Item being moved 1844 | Old index 1845 | New index 1846 | 1847 | 1848 | 1849 | Item being repositioned in the DataGrid 1850 | 1851 | 1852 | 1853 | 1854 | Old index of the item 1855 | 1856 | 1857 | 1858 | 1859 | New index of the item 1860 | 1861 | 1862 | 1863 | 1864 | --------------------------------------------------------------------------------