├── .gitattributes ├── .gitignore ├── Common ├── CommonProperties.cs └── Mallardsoft.snk ├── LICENSE ├── NuGet ├── App │ ├── UpdateControls.App.nuspec │ └── content │ │ ├── Models │ │ ├── Document.cs.pp │ │ ├── Item.cs.pp │ │ └── Selection.cs.pp │ │ ├── Readme_UpdateControls.txt.pp │ │ └── ViewModels │ │ ├── ItemHeader.cs.pp │ │ ├── ItemViewModel.cs.pp │ │ ├── MainViewModel.cs.pp │ │ └── ViewModelLocator.cs.pp ├── Core │ └── updatecontrols.nuspec ├── Forms │ └── UpdateControls.Forms.nuspec └── Snippets │ ├── content │ └── Readme_UpdateControls_Snippets.txt │ ├── tools │ ├── dep.snippet │ ├── depList.snippet │ ├── ind.snippet │ ├── indList.snippet │ ├── install.ps1 │ └── uninstall.ps1 │ └── updatecontrols.snippets.nuspec ├── Portable ├── UpdateControls.UnitTest │ ├── CollectionContentTest.cs │ ├── CollectionData │ │ ├── SourceCollection.cs │ │ └── TargetCollection.cs │ ├── CollectionTest.cs │ ├── ContactListData │ │ ├── Contact.cs │ │ ├── ContactList.cs │ │ ├── ContactListSortOrder.cs │ │ ├── ContactListViewModel.cs │ │ └── ContactViewModel.cs │ ├── DependentListTest.cs │ ├── DirectConcurrencyTest.cs │ ├── DirectDependent.cs │ ├── DirectDependentTest.cs │ ├── DynamicSortOrderTest.cs │ ├── IndirectConcurrencyTest.cs │ ├── IndirectDependent.cs │ ├── IndirectDependentTest.cs │ ├── MemoryLeakTest.cs │ ├── MultithreadedData │ │ ├── SourceThread.cs │ │ └── TargetThread.cs │ ├── MultithreadedTest.cs │ ├── NotificationTest.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SortedCollectionTest.cs │ ├── SourceData.cs │ └── UpdateControls.UnitTest.csproj └── UpdateControls │ ├── Collections │ ├── DependentDictionary.cs │ ├── DependentList.cs │ ├── Impl │ │ └── UpdateCollectionHelper.cs │ ├── IndependentDictionary.cs │ └── IndependentList.cs │ ├── Dependent.cs │ ├── DependentJob.cs │ ├── Fields │ ├── Dependent.cs │ └── Independent.cs │ ├── IUpdatable.cs │ ├── Independent.cs │ ├── InertialProperty.cs │ ├── MemoizedTypeName.cs │ ├── NamedPrecedents.cs │ ├── Precedent.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── RecycleBin.cs │ ├── ThreadLocal.cs │ ├── UpdateControls.csproj │ ├── UpdateControlsExtensions.cs │ ├── UpdateScheduler.cs │ └── XAML │ └── MakeCommand.cs ├── README.md ├── Silverlight └── UpdateControls.XAML │ ├── ForView.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── UpdateControls.XAML.csproj │ ├── ViewModelBase.cs │ ├── ViewModelLocatorBase.cs │ └── Wrapper │ ├── ClassInstance.cs │ ├── ClassProperty.cs │ ├── CollectionItem.cs │ ├── DelegatedPropertyInfo.cs │ ├── DelegatedType.cs │ ├── IObjectInstance.cs │ ├── NotificationGate.cs │ ├── ObjectInstance.cs │ ├── ObjectProperty.cs │ ├── ObjectPropertyAtom.cs │ ├── ObjectPropertyAtomNative.cs │ ├── ObjectPropertyAtomObject.cs │ ├── ObjectPropertyCollection.cs │ ├── ObjectPropertyCollectionNative.cs │ └── ObjectPropertyCollectionObject.cs ├── Universal ├── UpdateControls.Test │ ├── ContactList.cs │ ├── ContactListNavigationModel.cs │ ├── ContactListViewModel.cs │ ├── DataGridPersonViewModel.cs │ ├── GenderEnum.cs │ ├── GenderOption.cs │ ├── ISpouseViewModel.cs │ ├── Person.cs │ ├── PersonViewModel.cs │ ├── PersonViewModelBase.cs │ ├── PrefixID.cs │ ├── PrefixViewModel.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SpouseViewModel.cs │ └── UpdateControls.Test.csproj ├── UpdateControls.XAML │ ├── ForView.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── UpdateControls.XAML.csproj │ ├── ViewModelBase.cs │ ├── ViewModelLocatorBase.cs │ └── Wrapper │ │ ├── CollectionItem.cs │ │ ├── CustomMemberProvider.cs │ │ ├── CustomMetadataProvider.cs │ │ ├── CustomTypeProvider.cs │ │ ├── ObjectInstance.cs │ │ ├── ObjectProperty.cs │ │ └── PrimitiveTypeProvider.cs └── UpdateControls │ ├── Collections │ ├── DependentDictionary.cs │ ├── DependentList.cs │ ├── Impl │ │ └── UpdateCollectionHelper.cs │ ├── IndependentDictionary.cs │ └── IndependentList.cs │ ├── Dependent.cs │ ├── Fields │ ├── Dependent.cs │ └── Independent.cs │ ├── IUpdatable.cs │ ├── Independent.cs │ ├── InertialProperty.cs │ ├── Precedent.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── RecycleBin.cs │ ├── UpdateControls.csproj │ ├── UpdateControlsExtensions.cs │ ├── UpdateScheduler.cs │ └── XAML │ └── MakeCommand.cs ├── UpdateControls.sln ├── WPF └── UpdateControls.XAML │ ├── BindingInterceptor.cs │ ├── ForView.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Timers │ ├── DroppingTimeSpan.cs │ ├── FloatingDateTime.cs │ ├── FloatingTimeSpan.cs │ ├── FloatingTimeZone.cs │ ├── IndependentTimer.cs │ ├── RisingTimeSpan.cs │ └── UtcTimeZone.cs │ ├── UpdateControls.XAML.csproj │ ├── ViewModelBase.cs │ ├── ViewModelLocatorBase.cs │ └── Wrapper │ ├── ClassEvent.cs │ ├── ClassInstance.cs │ ├── ClassInstanceProvider.cs │ ├── ClassMember.cs │ ├── ClassMemberCommand.cs │ ├── ClassMemberField.cs │ ├── ClassMemberIndependent.cs │ ├── ClassMemberProperty.cs │ ├── CollectionItem.cs │ ├── IObjectInstance.cs │ ├── ObjectInstance.cs │ ├── ObjectProperty.cs │ ├── ObjectPropertyAtom.cs │ ├── ObjectPropertyAtomNative.cs │ ├── ObjectPropertyAtomObject.cs │ ├── ObjectPropertyCollection.cs │ ├── ObjectPropertyCollectionNative.cs │ ├── ObjectPropertyCollectionObject.cs │ └── ObjectPropertyCommand.cs ├── WindowsForms ├── UpdateControls.Forms │ ├── Delegates.cs │ ├── GuiUpdateHelper.cs │ ├── IEnabledControl.cs │ ├── IErrorControl.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ToolboxImages │ │ ├── UpdateButton.png │ │ ├── UpdateCheckBox.png │ │ ├── UpdateCheckedListBox.png │ │ ├── UpdateComboBox.png │ │ ├── UpdateComponent.png │ │ ├── UpdateDateTimePicker.png │ │ ├── UpdateErrorProvider.png │ │ ├── UpdateFormMap.png │ │ ├── UpdateGrid.png │ │ ├── UpdateLabel.png │ │ ├── UpdateListBox.png │ │ ├── UpdateListView.png │ │ ├── UpdateMonthCalendar.png │ │ ├── UpdateRadioButton.png │ │ ├── UpdateTextBox.png │ │ └── UpdateTreeView.png │ ├── UpdateButton.cs │ ├── UpdateButton.resx │ ├── UpdateCheckBox.cs │ ├── UpdateCheckBox.resx │ ├── UpdateCheckedListBox.cs │ ├── UpdateCheckedListBox.resx │ ├── UpdateComboBox.cs │ ├── UpdateComboBox.resx │ ├── UpdateComponent.cs │ ├── UpdateComponent.resx │ ├── UpdateControls.Forms.csproj │ ├── UpdateDateTimePicker.cs │ ├── UpdateDateTimePicker.resx │ ├── UpdateErrorProvider.Designer.cs │ ├── UpdateErrorProvider.cs │ ├── UpdateErrorProvider.resx │ ├── UpdateFormMap.cs │ ├── UpdateFormMap.resx │ ├── UpdateGrid.cs │ ├── UpdateGrid.resx │ ├── UpdateLabel.cs │ ├── UpdateLabel.resx │ ├── UpdateListBox.cs │ ├── UpdateListBox.resx │ ├── UpdateListView.cs │ ├── UpdateListView.resx │ ├── UpdateMonthCalendar.cs │ ├── UpdateMonthCalendar.resx │ ├── UpdateNumericUpDown.cs │ ├── UpdateRadioButton.cs │ ├── UpdateRadioButton.resx │ ├── UpdateTextBox.cs │ ├── UpdateTextBox.resx │ ├── UpdateTreeView.cs │ ├── UpdateTreeView.resx │ └── Util │ │ ├── CollectionHelper.cs │ │ ├── ReadOnlyListDecorator.cs │ │ └── UpdateController.cs └── UpdateControls │ ├── Collections │ ├── DependentDictionary.cs │ ├── DependentList.cs │ ├── Impl │ │ └── UpdateCollectionHelper.cs │ ├── IndependentDictionary.cs │ └── IndependentList.cs │ ├── Dependent.CurrentUpdate.cs │ ├── Dependent.cs │ ├── Fields │ ├── Dependent.cs │ └── Independent.cs │ ├── IUpdatable.cs │ ├── Independent.cs │ ├── InertialProperty.cs │ ├── MemoizedTypeName.cs │ ├── NamedPrecedents.cs │ ├── Precedent.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── RecycleBin.cs │ ├── ThreadLocal.cs │ ├── UpdateControls.csproj │ ├── UpdateControlsExtensions.cs │ └── UpdateScheduler.cs ├── WindowsPhone └── UpdateControls.XAML │ ├── ForView.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── UpdateControls.XAML.csproj │ ├── ViewModelBase.cs │ ├── ViewModelLocatorBase.cs │ └── Wrapper │ ├── ClassInstance.cs │ ├── ClassProperty.cs │ ├── CollectionItem.cs │ ├── IObjectInstance.cs │ ├── NotificationGate.cs │ ├── ObjectInstance.cs │ ├── ObjectProperty.cs │ ├── ObjectPropertyAtom.cs │ ├── ObjectPropertyCollection.cs │ ├── Tree.cs │ └── UnitTestDispatcher.cs └── WindowsStore └── UpdateControls.Test.App ├── App.xaml ├── App.xaml.cs ├── Assets ├── Logo.png ├── SmallLogo.png ├── SplashScreen.png └── StoreLogo.png ├── Common └── StandardStyles.xaml ├── DebugConverter.cs ├── MainPage.xaml ├── MainPage.xaml.cs ├── Package.appxmanifest ├── Properties └── AssemblyInfo.cs ├── UpdateControls.Test.App.csproj ├── UpdateControls.XAML.Test_TemporaryKey.pfx ├── ViewModelLocator.cs └── app.config /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | packages/ 2 | NuGet/Core/lib/ 3 | NuGet/Forms/lib/ 4 | .vs/ 5 | 6 | #ignore thumbnails created by windows 7 | Thumbs.db 8 | #Ignore files build by Visual Studio 9 | *.obj 10 | *.pdb 11 | *.user 12 | *.aps 13 | *.pch 14 | *.vspscc 15 | *_i.c 16 | *_p.c 17 | *.ncb 18 | *.suo 19 | *.tlb 20 | *.tlh 21 | *.bak 22 | *.cache 23 | *.ilk 24 | *.log 25 | [Bb]in 26 | [Dd]ebug*/ 27 | *.lib 28 | *.sbr 29 | obj/ 30 | [Rr]elease*/ 31 | _ReSharper*/ 32 | [Tt]est[Rr]esult* 33 | .svn/ 34 | *.[Mm][Dd][Ff] 35 | *.[Ll][Dd][Ff] 36 | *.dbmdl 37 | *.eto 38 | *.ncb 39 | *.user 40 | *.stuff 41 | ~*.* 42 | *.suo 43 | *.xap 44 | *.vs10x 45 | Index.dat 46 | Storage.dat 47 | Generated_Code*/ 48 | *.Publish.xml 49 | *.docstates 50 | AppPackages/ 51 | .cr/Settings.xml 52 | -------------------------------------------------------------------------------- /Common/CommonProperties.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System.Reflection; 13 | using System; 14 | 15 | [assembly: AssemblyDescription("")] 16 | [assembly: AssemblyConfiguration("")] 17 | [assembly: AssemblyCompany("Michael L Perry")] 18 | [assembly: AssemblyCopyright("Copyright 2014 Michael L Perry, MIT License")] 19 | [assembly: AssemblyTrademark("")] 20 | [assembly: AssemblyCulture("")] 21 | [assembly: AssemblyVersion("2.3.0.0")] 22 | [assembly: AssemblyFileVersion("2.3.2.0")] 23 | -------------------------------------------------------------------------------- /Common/Mallardsoft.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/Common/Mallardsoft.snk -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Michael L Perry 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /NuGet/App/UpdateControls.App.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | UpdateControls.App 5 | 1.1.0 6 | Michael L Perry 7 | Michael L Perry 8 | http://updatecontrols.codeplex.com/license 9 | http://updatecontrols.net/ 10 | http://updatecontrols.net/images/logosmall.png 11 | false 12 | Add a view model locator for use in an Update Controls application. 13 | Copyright 2012, Michael L Perry 14 | mvvm viewmodel databinding inotifypropertychanged inpc 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /NuGet/App/content/Models/Document.cs.pp: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using UpdateControls.Collections; 7 | using UpdateControls.Fields; 8 | 9 | namespace $rootnamespace$.Models 10 | { 11 | public class Document 12 | { 13 | private Independent _name = new Independent(); 14 | private IndependentList _items = new IndependentList(); 15 | 16 | public string Name 17 | { 18 | get { return _name; } 19 | set { _name.Value = value; } 20 | } 21 | 22 | public IEnumerable Items 23 | { 24 | get { return _items; } 25 | } 26 | 27 | public Item NewItem() 28 | { 29 | Item item = new Item(); 30 | _items.Add(item); 31 | return item; 32 | } 33 | 34 | public void DeleteItem(Item item) 35 | { 36 | _items.Remove(item); 37 | } 38 | 39 | public bool CanMoveDown(Item item) 40 | { 41 | return _items.IndexOf(item) < _items.Count - 1; 42 | } 43 | 44 | public bool CanMoveUp(Item item) 45 | { 46 | return _items.IndexOf(item) > 0; 47 | } 48 | 49 | public void MoveDown(Item item) 50 | { 51 | int index = _items.IndexOf(item); 52 | _items.RemoveAt(index); 53 | _items.Insert(index + 1, item); 54 | } 55 | 56 | public void MoveUp(Item item) 57 | { 58 | int index = _items.IndexOf(item); 59 | _items.RemoveAt(index); 60 | _items.Insert(index - 1, item); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /NuGet/App/content/Models/Item.cs.pp: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UpdateControls.Collections; 6 | using UpdateControls.Fields; 7 | 8 | namespace $rootnamespace$.Models 9 | { 10 | public class Item 11 | { 12 | private Independent _name = new Independent(); 13 | 14 | public string Name 15 | { 16 | get { return _name; } 17 | set { _name.Value = value; } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /NuGet/App/content/Models/Selection.cs.pp: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using UpdateControls.Fields; 3 | 4 | namespace $rootnamespace$.Models 5 | { 6 | public class Selection 7 | { 8 | private Independent _selectedItem = new Independent(); 9 | 10 | public Item SelectedItem 11 | { 12 | get { return _selectedItem; } 13 | set { _selectedItem.Value = value; } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /NuGet/App/content/Readme_UpdateControls.txt.pp: -------------------------------------------------------------------------------- 1 | Add the ViewModels namespace to App.xaml: 2 | 3 | 6 | 7 | 8 | Add the view model locator to the resource dictionary: 9 | 10 | 11 | 12 | ... 13 | 14 | 15 | 16 | 17 | 18 | Reference the view model locator in each view: 19 | 20 | 23 | -------------------------------------------------------------------------------- /NuGet/App/content/ViewModels/ItemHeader.cs.pp: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using $rootnamespace$.Models; 4 | 5 | namespace $rootnamespace$.ViewModels 6 | { 7 | public class ItemHeader 8 | { 9 | private readonly Item _item; 10 | 11 | public ItemHeader(Item Item) 12 | { 13 | _item = Item; 14 | } 15 | 16 | public Item Item 17 | { 18 | get { return _item; } 19 | } 20 | 21 | public string Name 22 | { 23 | get { return _item.Name ?? ""; } 24 | } 25 | 26 | public override bool Equals(object obj) 27 | { 28 | if (obj == this) 29 | return true; 30 | ItemHeader that = obj as ItemHeader; 31 | if (that == null) 32 | return false; 33 | return Object.Equals(this._item, that._item); 34 | } 35 | 36 | public override int GetHashCode() 37 | { 38 | return _item.GetHashCode(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /NuGet/App/content/ViewModels/ItemViewModel.cs.pp: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using $rootnamespace$.Models; 5 | 6 | namespace $rootnamespace$.ViewModels 7 | { 8 | public class ItemViewModel 9 | { 10 | private readonly Item _item; 11 | 12 | public ItemViewModel(Item Item) 13 | { 14 | _item = Item; 15 | } 16 | 17 | public string Name 18 | { 19 | get { return _item.Name; } 20 | set { _item.Name = value; } 21 | } 22 | 23 | public override bool Equals(object obj) 24 | { 25 | if (obj == this) 26 | return true; 27 | ItemViewModel that = obj as ItemViewModel; 28 | if (that == null) 29 | return false; 30 | return Object.Equals(this._item, that._item); 31 | } 32 | 33 | public override int GetHashCode() 34 | { 35 | return _item.GetHashCode(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /NuGet/App/content/ViewModels/ViewModelLocator.cs.pp: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using UpdateControls.XAML; 7 | using $rootnamespace$.Models; 8 | 9 | namespace $rootnamespace$.ViewModels 10 | { 11 | public class ViewModelLocator : ViewModelLocatorBase 12 | { 13 | private Document _document; 14 | private Selection _selection; 15 | 16 | public ViewModelLocator() 17 | { 18 | _document = LoadDocument(); 19 | _selection = new Selection(); 20 | } 21 | 22 | public object Main 23 | { 24 | get { return ViewModel(() => new MainViewModel(_document, _selection)); } 25 | } 26 | 27 | public object Item 28 | { 29 | get 30 | { 31 | return ViewModel(() => _selection.SelectedItem == null 32 | ? null 33 | : new ItemViewModel(_selection.SelectedItem)); 34 | } 35 | } 36 | 37 | private Document LoadDocument() 38 | { 39 | // TODO: Load your document here. 40 | Document document = new Document(); 41 | var one = document.NewItem(); 42 | one.Name = "One"; 43 | var two = document.NewItem(); 44 | two.Name = "Two"; 45 | var three = document.NewItem(); 46 | three.Name = "Three"; 47 | return document; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /NuGet/Core/updatecontrols.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | UpdateControls 5 | 2.3.3 6 | Michael L Perry 7 | Michael L Perry 8 | Automatically discover view model dependencies and databind without INotifyPropertyChanged. 9 | http://updatecontrols.codeplex.com/license 10 | http://updatecontrols.net/ 11 | http://updatecontrols.net/images/logosmall.png 12 | false 13 | en-US 14 | mvvm viewmodel databinding inotifypropertychanged inpc wpf silverlight wp7 15 | 16 | -------------------------------------------------------------------------------- /NuGet/Forms/UpdateControls.Forms.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | UpdateControls.Forms 5 | 2.3.3 6 | Michael L Perry 7 | Michael L Perry 8 | Dependency tracking MVVM framework for Windows Forms. 9 | http://updatecontrols.codeplex.com/license 10 | http://updatecontrols.net/ 11 | http://updatecontrols.net/images/logosmall.png 12 | false 13 | en-US 14 | mvvm viewmodel databinding winforms 15 | 16 | -------------------------------------------------------------------------------- /NuGet/Snippets/content/Readme_UpdateControls_Snippets.txt: -------------------------------------------------------------------------------- 1 | Use the following snippets to create independent and dependent properties: 2 | 3 | ind - Independent property 4 | An independent property is one that can change on its own. These will be the 5 | values of your data model. 6 | 7 | indlist - Independent list 8 | The user can add and remove items in an independent collection. These will be 9 | child collections in your data model. 10 | 11 | dep - Dependent property 12 | A dependenty property calculates its value from code. The user cannot change 13 | its value directly. They can only change the independent properties that the 14 | dependent depends upon. 15 | 16 | All view model properties are dependent by default. Only use this template 17 | to cache the dependent value when it is expensive to calculate. 18 | 19 | deplist - Dependent list 20 | A dependent list calculates its contents from a linq query. The user cannot 21 | add or remove items in this list. They can only change the independent lists 22 | and properties that the linq query depends upon. 23 | 24 | All view model lists are dependent by default. Only use this template to 25 | cache lists that are expensive to calculate, or are used by other properties 26 | of the view model. 27 | 28 | If these snippets aren't working for you, please remove and reinstall the 29 | UpdateControls.Snippets package. -------------------------------------------------------------------------------- /NuGet/Snippets/tools/dep.snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | dep 6 | dep 7 | Code snippet to help you make properties based on 'Dependent<T>', an Update Controls class that represents a value computed based on one or more Independents. Note: in most cases you should just write a normal property instead of using Dependent<T>. Dependent<T> is useful to cache the result of a computation when the value of the property is expensive to compute. 8 | David Piepgrass 9 | 10 | Expansion 11 | 12 |
13 | 14 | 15 | 16 | type 17 | string 18 | Data type 19 | 20 | 21 | name 22 | CalculatedProperty 23 | A name for this computed property 24 | 25 | 26 | expr 27 | TODO 28 | Write an expression here to compute the value of the Dependent 29 | 30 | 31 | _$name$; 32 | public $type$ $name$ 33 | { 34 | get { 35 | if (_$name$ == null) 36 | _$name$ = new Dependent<$type$>("$name$", 37 | () => $expr$); 38 | return _$name$.Value; 39 | } 40 | }]]> 41 | 42 | 43 |
44 |
-------------------------------------------------------------------------------- /NuGet/Snippets/tools/depList.snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | depList 6 | depList 7 | Code snippet for 'DependentList<T>', which is used to compute a list of values based on a set of other values that utilize Independent, Dependent or other classes in Update Controls. 8 | David Piepgrass 9 | 10 | Expansion 11 | 12 |
13 | 14 | 15 | 16 | type 17 | string 18 | Data type of each element 19 | 20 | 21 | name 22 | List 23 | Property Name 24 | 25 | 26 | expr 27 | return TODO; 28 | Write a LINQ query or other code to compute the list of items as IEnumerable<T%gt;. 29 | 30 | 31 | _$name$; 32 | public DependentList<$type$> $name$ 33 | { 34 | get { 35 | if (_$name$ == null) 36 | _$name$ = new DependentList<$type$>("$name$", () => { 37 | $expr$ 38 | }); 39 | return _$name$; 40 | } 41 | }]]> 42 | 43 | 44 |
45 |
-------------------------------------------------------------------------------- /NuGet/Snippets/tools/ind.snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | ind 6 | ind 7 | Code snippet for 'Independent<T>' 8 | David Piepgrass 9 | 10 | Expansion 11 | 12 |
13 | 14 | 15 | 16 | type 17 | string 18 | Data type 19 | 20 | 21 | name 22 | Name 23 | Property Name 24 | 25 | 26 | _$name$ = new Independent<$type$>("$name$", default($type$)); 27 | public $type$ $name$ 28 | { 29 | get { return _$name$.Value; } 30 | set { _$name$.Value = value; } 31 | }]]> 32 | 33 | 34 |
35 |
-------------------------------------------------------------------------------- /NuGet/Snippets/tools/indList.snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | indList 6 | indList 7 | Code snippet for 'IndependentList<T>' 8 | David Piepgrass 9 | 10 | Expansion 11 | 12 |
13 | 14 | 15 | 16 | type 17 | string 18 | Data type of each element 19 | 20 | 21 | name 22 | List 23 | Property Name 24 | 25 | 26 | _$name$ = new IndependentList<$type$>(); 27 | public IList<$type$> $name$ 28 | { 29 | get { return _$name$; } 30 | }]]> 31 | 32 | 33 |
34 |
-------------------------------------------------------------------------------- /NuGet/Snippets/tools/install.ps1: -------------------------------------------------------------------------------- 1 | # Install script for code snippets with NuGet 2 | # ============================================= 3 | # Written by Geert van Horrik (see http://blog.catenalogic.com) 4 | # 5 | # Version 1.0 / 2011-02-18 6 | # 7 | # Required call to get environment variables 8 | 9 | param($installPath, $toolsPath, $package, $project) 10 | 11 | # You only have to customize the $snippetFolder name below, 12 | # don't forget to rename the $snippetFolder of the other file 13 | # ("uninstall.ps1") as well 14 | 15 | $snippetFolder = "UpdateControls" 16 | 17 | # Actual script start 18 | $source = "$toolsPath\*.snippet" 19 | $vsVersions = @("2005", "2008", "2010") 20 | 21 | Foreach ($vsVersion in $vsVersions) 22 | { 23 | $myCodeSnippetsFolder = "$HOME\My Documents\Visual Studio $vsVersion\Code Snippets\Visual C#\My Code Snippets\" 24 | 25 | if (Test-Path $myCodeSnippetsFolder) 26 | { 27 | $destination = "$myCodeSnippetsFolder$snippetFolder" 28 | if (!($myCodeSnippetsFolder -eq $destination)) 29 | { 30 | if (!(Test-Path $destination)) 31 | { 32 | New-Item $destination -itemType "directory" 33 | } 34 | 35 | "Installing code snippets for Visual Studio $vsVersion" 36 | Copy-Item $source $destination 37 | } 38 | else 39 | { 40 | "Define a value for snippetFolder variable, cannot be empty" 41 | } 42 | } 43 | else 44 | { 45 | "Path not found $myCodeSnippetsFolder" 46 | } 47 | } -------------------------------------------------------------------------------- /NuGet/Snippets/tools/uninstall.ps1: -------------------------------------------------------------------------------- 1 | # Uninstall script for code snippets with NuGet 2 | # ============================================= 3 | # Written by Geert van Horrik (see http://blog.catenalogic.com) 4 | # 5 | # Version 1.0 / 2011-02-18 6 | # 7 | # Required call to get environment variables 8 | 9 | param($installPath, $toolsPath, $package, $project) 10 | 11 | # You only have to customize the $snippetFolder name below, 12 | # don't forget to rename the $snippetFolder of the other file 13 | # ("install.ps1") as well 14 | 15 | $snippetFolder = "UpdateControls" 16 | 17 | # Actual script start 18 | $vsVersions = @("2005", "2008", "2010") 19 | 20 | Foreach ($vsVersion in $vsVersions) 21 | { 22 | $myCodeSnippetsFolder = "$HOME\My Documents\Visual Studio $vsVersion\Code Snippets\Visual C#\My Code Snippets\" 23 | if (Test-Path $myCodeSnippetsFolder) 24 | { 25 | $destination = "$myCodeSnippetsFolder$snippetFolder" 26 | if (!($myCodeSnippetsFolder -eq $destination)) 27 | { 28 | if (Test-Path $destination) 29 | { 30 | "Uninstalling code snippets for Visual Studio $vsVersion" 31 | Remove-Item $destination -recurse -force 32 | } 33 | } 34 | else 35 | { 36 | "Define a value for snippetFolder variable, cannot be empty" 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /NuGet/Snippets/updatecontrols.snippets.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | UpdateControls.Snippets 5 | 2.2.1.0 6 | Qwertie 7 | Michael L Perry 8 | Code snippets for Update Controls. 9 | http://updatecontrols.codeplex.com/license 10 | http://updatecontrols.net/ 11 | http://updatecontrols.net/images/logosmall.png 12 | false 13 | en-US 14 | mvvm viewmodel databinding inotifypropertychanged inpc wpf silverlight wp7 15 | 16 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/CollectionContentTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using UpdateControls.UnitTest.ContactListData; 3 | using System.Linq; 4 | 5 | namespace UpdateControls.UnitTest 6 | { 7 | [TestClass] 8 | public class CollectionContentTest 9 | { 10 | private ContactList _contactList; 11 | private ContactListViewModel _viewModel; 12 | private int _collectionChangedCount; 13 | 14 | [TestInitialize] 15 | public void Initialize() 16 | { 17 | _contactList = new ContactList(); 18 | _viewModel = new ContactListViewModel(_contactList); 19 | _contactList.AddContact(new Contact() { FirstName = "Michael", LastName = "Perry" }); 20 | _contactList.AddContact(new Contact() { FirstName = "Ada", LastName = "Lovelace" }); 21 | _contactList.AddContact(new Contact() { FirstName = "Charles", LastName = "Babbage" }); 22 | 23 | _collectionChangedCount = 0; 24 | _viewModel.ContactsCollectionChanged += 25 | delegate 26 | { 27 | _collectionChangedCount++; 28 | }; 29 | } 30 | 31 | [TestMethod] 32 | public void WhenContactAddedShouldNotifyCollectionChanged() 33 | { 34 | ContactViewModel firstByDefaultOrder = _viewModel.Contacts.First(); 35 | _contactList.AddContact(new Contact() { FirstName = "Martin", LastName = "Fowler" }); 36 | 37 | Assert.AreEqual(1, _collectionChangedCount); 38 | } 39 | 40 | [TestMethod] 41 | public void WhenContactDeletedShouldNotifyCollectionChanged() 42 | { 43 | ContactViewModel firstByDefaultOrder = _viewModel.Contacts.First(); 44 | _contactList.DeleteContact(_contactList.Contacts.First()); 45 | 46 | Assert.AreEqual(1, _collectionChangedCount); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/CollectionData/SourceCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace UpdateControls.UnitTest.CollectionData 4 | { 5 | public class SourceCollection 6 | { 7 | private List _numbers = new List(); 8 | private Independent _indNumbers = new Independent(); 9 | 10 | public void Insert(int number) 11 | { 12 | _indNumbers.OnSet(); 13 | _numbers.Add(number); 14 | } 15 | 16 | public IEnumerable Numbers 17 | { 18 | get { _indNumbers.OnGet(); return _numbers; } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/CollectionData/TargetCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace UpdateControls.UnitTest.CollectionData 5 | { 6 | public class TargetCollection 7 | { 8 | private SourceCollection _source; 9 | private List _results = new List(); 10 | private Dependent _depResults; 11 | 12 | public TargetCollection(SourceCollection source) 13 | { 14 | _source = source; 15 | _depResults = new Dependent(UpdateResults); 16 | } 17 | 18 | public IEnumerable Results 19 | { 20 | get { _depResults.OnGet(); return _results; } 21 | } 22 | 23 | private void UpdateResults() 24 | { 25 | _results = _source.Numbers.Select(number => number + 1).ToList(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/CollectionTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using UpdateControls.UnitTest.CollectionData; 4 | 5 | namespace UpdateControls.UnitTest 6 | { 7 | [TestClass] 8 | public class CollectionTest 9 | { 10 | private SourceCollection _source; 11 | 12 | [TestInitialize] 13 | public void Initialize() 14 | { 15 | _source = new SourceCollection(); 16 | } 17 | 18 | [TestMethod] 19 | public void InsertIntoSourceShouldCauseNewElementInTarget() 20 | { 21 | TargetCollection target = new TargetCollection(_source); 22 | 23 | _source.Insert(3); 24 | int firstNumber = target.Results.Single(); 25 | Assert.AreEqual(4, firstNumber); 26 | } 27 | 28 | [TestMethod] 29 | public void InsertIntoSourceBeforeTargetCreatedShouldCauseNewElementInTarget() 30 | { 31 | _source.Insert(3); 32 | 33 | TargetCollection target = new TargetCollection(_source); 34 | 35 | int firstNumber = target.Results.Single(); 36 | Assert.AreEqual(4, firstNumber); 37 | } 38 | 39 | [TestMethod] 40 | public void InsertASecondIntoSourceTargetShouldUpdate() 41 | { 42 | TargetCollection target = new TargetCollection(_source); 43 | _source.Insert(42); 44 | target.Results.Single(); 45 | 46 | _source.Insert(43); 47 | int[] results = target.Results.ToArray(); 48 | 49 | Assert.AreEqual(2, results.Length); 50 | Assert.AreEqual(43, results[0]); 51 | Assert.AreEqual(44, results[1]); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/ContactListData/Contact.cs: -------------------------------------------------------------------------------- 1 | using UpdateControls; 2 | 3 | namespace UpdateControls.UnitTest.ContactListData 4 | { 5 | public class Contact 6 | { 7 | private string _firstName; 8 | private string _lastName; 9 | 10 | #region Independent properties 11 | // Generated by Update Controls -------------------------------- 12 | private Independent _indFirstName = new Independent(); 13 | private Independent _indLastName = new Independent(); 14 | 15 | public string FirstName 16 | { 17 | get { _indFirstName.OnGet(); return _firstName; } 18 | set { _indFirstName.OnSet(); _firstName = value; } 19 | } 20 | 21 | public string LastName 22 | { 23 | get { _indLastName.OnGet(); return _lastName; } 24 | set { _indLastName.OnSet(); _lastName = value; } 25 | } 26 | // End generated code -------------------------------- 27 | #endregion 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/ContactListData/ContactList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UpdateControls.Collections; 3 | 4 | namespace UpdateControls.UnitTest.ContactListData 5 | { 6 | public class ContactList 7 | { 8 | private IndependentList _contacts = new IndependentList(); 9 | 10 | public void AddContact(Contact contact) 11 | { 12 | _contacts.Add(contact); 13 | } 14 | 15 | public void AddContacts(IEnumerable contacts) 16 | { 17 | _contacts.AddRange(contacts); 18 | } 19 | 20 | public void DeleteContact(Contact contact) 21 | { 22 | _contacts.Remove(contact); 23 | } 24 | 25 | public IEnumerable Contacts 26 | { 27 | get { return _contacts; } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/ContactListData/ContactListSortOrder.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace UpdateControls.UnitTest.ContactListData 3 | { 4 | public enum ContactListSortOrder 5 | { 6 | NoOrder, 7 | FirstName, 8 | LastName 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/ContactListData/ContactListViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace UpdateControls.UnitTest.ContactListData 6 | { 7 | public class ContactListViewModel 8 | { 9 | private ContactList _contactList; 10 | private ContactListSortOrder _sortOrder; 11 | private Independent _indSortOrder = new Independent(); 12 | 13 | private List _contactViewModels; 14 | private Dependent _depContactViewModels; 15 | 16 | public delegate void NotifyCollectionChanged(); 17 | public event NotifyCollectionChanged ContactsCollectionChanged; 18 | 19 | public ContactListViewModel(ContactList contactList) 20 | { 21 | _contactList = contactList; 22 | _depContactViewModels = new Dependent(UpdateContactViewModels); 23 | _depContactViewModels.Invalidated += new Action(_depContactViewModels_Invalidated); 24 | } 25 | 26 | void _depContactViewModels_Invalidated() 27 | { 28 | ContactsCollectionChanged(); 29 | } 30 | 31 | public ContactListSortOrder SortOrder 32 | { 33 | get 34 | { 35 | _indSortOrder.OnGet(); 36 | return _sortOrder; 37 | } 38 | set 39 | { 40 | if (_sortOrder != value) _indSortOrder.OnSet(); 41 | _sortOrder = value; 42 | } 43 | } 44 | 45 | public IEnumerable Contacts 46 | { 47 | get 48 | { 49 | _depContactViewModels.OnGet(); 50 | return _contactViewModels; 51 | } 52 | } 53 | 54 | private void UpdateContactViewModels() 55 | { 56 | IEnumerable contacts = _contactList.Contacts; 57 | if (SortOrder == ContactListSortOrder.FirstName) 58 | contacts = contacts.OrderBy(contact => contact.FirstName); 59 | else if (SortOrder == ContactListSortOrder.LastName) 60 | contacts = contacts.OrderBy(contact => contact.LastName); 61 | 62 | _contactViewModels = contacts 63 | .Select(contact => new ContactViewModel(contact)) 64 | .ToList(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/ContactListData/ContactViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace UpdateControls.UnitTest.ContactListData 4 | { 5 | public class ContactViewModel 6 | { 7 | private Contact _contact; 8 | 9 | public ContactViewModel(Contact contact) 10 | { 11 | _contact = contact; 12 | } 13 | 14 | public string FullName 15 | { 16 | get 17 | { 18 | return string.Format("{0} {1}", _contact.FirstName, _contact.LastName); 19 | } 20 | } 21 | 22 | public override bool Equals(object obj) 23 | { 24 | if (this == obj) 25 | return true; 26 | ContactViewModel that = obj as ContactViewModel; 27 | if (that == null) 28 | return false; 29 | return _contact == that._contact; 30 | } 31 | 32 | public override int GetHashCode() 33 | { 34 | return _contact.GetHashCode(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/DirectDependent.cs: -------------------------------------------------------------------------------- 1 | using UpdateControls.Fields; 2 | 3 | namespace UpdateControls.UnitTest 4 | { 5 | public class DirectDependent 6 | { 7 | private SourceData _source; 8 | 9 | private Dependent _property; 10 | 11 | public DirectDependent(SourceData source) 12 | { 13 | _source = source; 14 | _property = new Dependent(() => _source.SourceProperty); 15 | } 16 | 17 | public int DependentProperty 18 | { 19 | get { return _property; } 20 | } 21 | 22 | public bool IsUpToDate 23 | { 24 | get { return _property.DependentSentry.IsUpToDate; } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/IndirectDependent.cs: -------------------------------------------------------------------------------- 1 | using UpdateControls.Fields; 2 | 3 | namespace UpdateControls.UnitTest 4 | { 5 | public class IndirectDependent 6 | { 7 | private DirectDependent _indermediateDependent; 8 | 9 | private Dependent _property; 10 | 11 | public IndirectDependent(DirectDependent indermediateDependent) 12 | { 13 | _indermediateDependent = indermediateDependent; 14 | _property = new Dependent(() => _indermediateDependent.DependentProperty); 15 | } 16 | 17 | public int DependentProperty 18 | { 19 | get { return _property; } 20 | } 21 | 22 | public bool IsUpToDate 23 | { 24 | get { return _property.DependentSentry.IsUpToDate; } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/MultithreadedData/SourceThread.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using UpdateControls.Fields; 3 | 4 | namespace UpdateControls.UnitTest.MultithreadedData 5 | { 6 | public class SourceThread 7 | { 8 | public const int MaxValue = 10000; 9 | 10 | private Thread _thread; 11 | private Independent _value = new Independent(); 12 | 13 | public SourceThread() 14 | { 15 | _thread = new Thread(ThreadProc); 16 | } 17 | 18 | public void Start() 19 | { 20 | _thread.Start(); 21 | } 22 | 23 | public void Join() 24 | { 25 | _thread.Join(); 26 | } 27 | 28 | private void ThreadProc() 29 | { 30 | for (int i = 0; i <= MaxValue; i++) 31 | { 32 | Value = i; 33 | } 34 | } 35 | 36 | public int Value 37 | { 38 | get 39 | { 40 | lock (this) 41 | return _value; 42 | } 43 | set 44 | { 45 | lock (this) 46 | _value.Value = value; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/MultithreadedData/TargetThread.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading; 4 | using UpdateControls.Fields; 5 | 6 | namespace UpdateControls.UnitTest.MultithreadedData 7 | { 8 | public class TargetThread 9 | { 10 | private SourceThread[] _sources; 11 | private Thread _thread; 12 | private Dependent _total; 13 | 14 | public TargetThread(SourceThread[] sources) 15 | { 16 | _sources = sources; 17 | _thread = new Thread(ThreadProc); 18 | _total = new Dependent(() => _sources.Sum(source => source.Value)); 19 | } 20 | 21 | public void Start() 22 | { 23 | _thread.Start(); 24 | } 25 | 26 | public void Join() 27 | { 28 | _thread.Join(); 29 | } 30 | 31 | public int Total 32 | { 33 | get 34 | { 35 | lock (this) 36 | return _total; 37 | } 38 | } 39 | 40 | private void ThreadProc() 41 | { 42 | for (int i = 0; i < SourceThread.MaxValue; i++) 43 | { 44 | int total = Total; 45 | if (total < 0) // This will never happen, but we need to ensure that the property get is not optimized out. 46 | throw new InvalidOperationException(); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/MultithreadedTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | using UpdateControls.UnitTest.MultithreadedData; 7 | 8 | namespace UpdateControls.UnitTest 9 | { 10 | [TestClass] 11 | public class MultithreadedTest 12 | { 13 | [TestMethod] 14 | public void IsThreadSafe() 15 | { 16 | const int ThreadCount = 10; 17 | 18 | // Start source threads. 19 | SourceThread[] sources = new SourceThread[ThreadCount]; 20 | for (int i = 0; i < ThreadCount; i++) 21 | { 22 | sources[i] = new SourceThread(); 23 | sources[i].Start(); 24 | } 25 | 26 | // Start target threads. 27 | TargetThread[] targets = new TargetThread[ThreadCount]; 28 | for (int i = 0; i < ThreadCount; i++) 29 | { 30 | targets[i] = new TargetThread(sources); 31 | targets[i].Start(); 32 | } 33 | 34 | // Wait for all threads to finish. 35 | for (int i = 0; i < ThreadCount; i++) 36 | { 37 | sources[i].Join(); 38 | targets[i].Join(); 39 | } 40 | 41 | // All targets are in the correct state. 42 | for (int i = 0; i < ThreadCount; i++) 43 | { 44 | Assert.AreEqual(ThreadCount * SourceThread.MaxValue, targets[i].Total); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/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("UpdateControls.UnitTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("UpdateControls.UnitTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 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("93f186f5-6e37-40b1-8767-4c2305929548")] 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 | -------------------------------------------------------------------------------- /Portable/UpdateControls.UnitTest/SourceData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using UpdateControls.Fields; 4 | 5 | namespace UpdateControls.UnitTest 6 | { 7 | public class SourceData 8 | { 9 | private Independent _sourceProperty = new Independent(); 10 | private AutoResetEvent _continue = new AutoResetEvent(false); 11 | 12 | public int SourceProperty 13 | { 14 | get 15 | { 16 | int result = _sourceProperty; 17 | ThreadPool.QueueUserWorkItem(o => 18 | { 19 | if (AfterGet != null) 20 | AfterGet(); 21 | _continue.Set(); 22 | }); 23 | _continue.WaitOne(); 24 | return result; 25 | } 26 | set { _sourceProperty.Value = value; } 27 | } 28 | 29 | public event Action AfterGet; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Portable/UpdateControls/Collections/DependentList.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2011 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | namespace UpdateControls.Collections 16 | { 17 | public class DependentList : IEnumerable 18 | { 19 | private readonly Func> _computeCollection; 20 | 21 | private List _list = new List(); 22 | private Dependent _dependentSentry; 23 | 24 | public DependentList(Func> computeCollection) 25 | { 26 | _computeCollection = computeCollection; 27 | 28 | _dependentSentry = new NamedDependent(MemoizedTypeName>.GenericName(), 29 | delegate { 30 | using (var bin = new RecycleBin(_list)) 31 | { 32 | _list.Clear(); 33 | 34 | foreach (T item in computeCollection()) 35 | _list.Add(bin.Extract(item)); 36 | } 37 | }); 38 | } 39 | 40 | public int IndexOf(T item) 41 | { 42 | _dependentSentry.OnGet(); 43 | return _list.IndexOf(item); 44 | } 45 | 46 | public T this[int index] 47 | { 48 | get 49 | { 50 | _dependentSentry.OnGet(); 51 | return _list[index]; 52 | } 53 | } 54 | 55 | public bool Contains(T item) 56 | { 57 | _dependentSentry.OnGet(); 58 | return _list.Contains(item); 59 | } 60 | 61 | public void CopyTo(T[] array, int arrayIndex) 62 | { 63 | _dependentSentry.OnGet(); 64 | _list.CopyTo(array, arrayIndex); 65 | } 66 | 67 | public int Count 68 | { 69 | get { _dependentSentry.OnGet(); return _list.Count; } 70 | } 71 | 72 | public IEnumerator GetEnumerator() 73 | { 74 | _dependentSentry.OnGet(); 75 | return _list.GetEnumerator(); 76 | } 77 | 78 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 79 | { 80 | _dependentSentry.OnGet(); 81 | return ((System.Collections.IEnumerable)_list).GetEnumerator(); 82 | } 83 | 84 | public Dependent DependentSentry 85 | { 86 | get { return _dependentSentry; } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Portable/UpdateControls/Collections/Impl/UpdateCollectionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls.Collections.Impl 7 | { 8 | /// Helper structure used by DependentDictionary and 9 | /// IndependentDictionary to represent the "Keys" and "Values" members. 10 | /// 11 | /// If you save a reference to the Keys or Values property of , 12 | /// the independent sentry should be informed when that collection is accessed. 13 | /// This helper class ensures that the sentry is notified. 14 | /// 15 | /// For , this class is even more 16 | /// important. Whenever DependentDictionary is updated, a new dictionary is 17 | /// created to hold the updated content, so the Keys and Values collections 18 | /// change frequently. This wrapper ensure that you do not accidentally hold 19 | /// a reference to an out-of-date version of the Keys or Values collection. 20 | /// It also ensures that the dictionary is updated if necessary when it is 21 | /// accessed through the Keys or Values collection. 22 | /// 23 | public struct UpdateCollectionHelper : ICollection 24 | { 25 | readonly Func> _get; 26 | 27 | public UpdateCollectionHelper(Func> getCollection) 28 | { 29 | _get = getCollection; 30 | } 31 | 32 | public void Add(T item) 33 | { 34 | throw new NotSupportedException(); 35 | } 36 | public void Clear() 37 | { 38 | throw new NotSupportedException(); 39 | } 40 | public bool Contains(T item) 41 | { 42 | return _get().Contains(item); 43 | } 44 | public void CopyTo(T[] array, int arrayIndex) 45 | { 46 | _get().CopyTo(array, arrayIndex); 47 | } 48 | public int Count 49 | { 50 | get { return _get().Count; } 51 | } 52 | public bool IsReadOnly 53 | { 54 | get { return true; } 55 | } 56 | public bool Remove(T item) 57 | { 58 | throw new NotSupportedException(); 59 | } 60 | 61 | public IEnumerator GetEnumerator() 62 | { 63 | return _get().GetEnumerator(); 64 | } 65 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 66 | { 67 | return GetEnumerator(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Portable/UpdateControls/DependentJob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls 7 | { 8 | public class DependentJob : IUpdatable, IDisposable 9 | { 10 | Dependent _dependent; 11 | bool _running; 12 | 13 | public DependentJob(Action action) 14 | { 15 | _dependent = new Dependent(action); 16 | _dependent.Invalidated += () => UpdateScheduler.ScheduleUpdate(this); 17 | } 18 | 19 | public void Start() 20 | { 21 | if (_dependent == null) 22 | throw new InvalidOperationException("Cannot restart DependentJob"); 23 | _running = true; 24 | UpdateScheduler.ScheduleUpdate(this); 25 | } 26 | 27 | public void Stop() 28 | { 29 | _running = false; 30 | _dependent.Dispose(); 31 | _dependent = null; 32 | } 33 | 34 | public void Dispose() { Stop(); } 35 | 36 | void IUpdatable.UpdateNow() 37 | { 38 | if (_running) 39 | _dependent.OnGet(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Portable/UpdateControls/Fields/Dependent.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2011 Michael L Perry 5 | * MIT License 6 | * 7 | * This class based on a contribution by David Piepgrass. 8 | * 9 | * http://updatecontrols.net 10 | * http://www.codeplex.com/updatecontrols/ 11 | * 12 | **********************************************************************/ 13 | 14 | using System; 15 | using System.ComponentModel; 16 | 17 | namespace UpdateControls.Fields 18 | { 19 | public class Dependent : NamedDependent 20 | { 21 | protected internal T _value; 22 | protected Func _computeValue; 23 | 24 | public Dependent(Func compute) : base((string)null, null) 25 | { 26 | base._update = Update; _computeValue = compute; 27 | } 28 | public Dependent(string name, Func compute) : base(name, null) 29 | { 30 | base._update = Update; _computeValue = compute; 31 | } 32 | 33 | protected void Update() 34 | { 35 | _value = _computeValue(); 36 | // TODO: don't propagate updates when _value did not change. 37 | // T oldValue = _value; 38 | // _value = _computeValue(); 39 | // return _value == null ? oldValue != null : !_value.Equals(oldValue); 40 | } 41 | 42 | public T Value 43 | { 44 | get { base.OnGet(); return _value; } 45 | } 46 | public static implicit operator T(Dependent dependent) 47 | { 48 | return dependent.Value; 49 | } 50 | 51 | public override string VisualizerName(bool withValue) 52 | { 53 | string s = VisualizerName(_name ?? "NamedDependent"); 54 | if (withValue) 55 | s += " = " + (_value == null ? "null" : _value.ToString()); 56 | return s; 57 | } 58 | internal static string VisualizerName(string name) 59 | { 60 | string typeName = MemoizedTypeName.GenericName(); 61 | if (!string.IsNullOrEmpty(name)) 62 | return string.Format("{0}: {1}", name, typeName); 63 | else 64 | return typeName; 65 | } 66 | 67 | [Obsolete, EditorBrowsable(EditorBrowsableState.Never)] 68 | public Dependent DependentSentry 69 | { 70 | get { return this; } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Portable/UpdateControls/Fields/Independent.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2011 Michael L Perry 5 | * MIT License 6 | * 7 | * This class based on a contribution by David Piepgrass. 8 | * 9 | * http://updatecontrols.net 10 | * http://www.codeplex.com/updatecontrols/ 11 | * 12 | **********************************************************************/ 13 | using System; 14 | using System.ComponentModel; 15 | 16 | namespace UpdateControls.Fields 17 | { 18 | public class Independent : NamedIndependent 19 | { 20 | protected internal T _value; 21 | 22 | public Independent() { } 23 | public Independent(T value) : this((string)null, value) { } 24 | 25 | // Oops, this constructor causes ambiguity in case of Independent. 26 | // In that case, C# compilers will reinterpret existing code that previously 27 | // used the Independent(value) constructor to call Independent(name) instead. 28 | //public Independent(string name) : base(name) { } 29 | 30 | public Independent(string name, T value) : base(name) { _value = value; } 31 | public Independent(Type containerType, string name) : base(containerType, name) { } 32 | public Independent(Type containerType, string name, T value) : base(containerType, name) { _value = value; } 33 | 34 | public T Value 35 | { 36 | get { base.OnGet(); return _value; } 37 | set { 38 | if (_value == null ? value != null : !_value.Equals(value)) 39 | { 40 | base.OnSet(); 41 | _value = value; 42 | } 43 | } 44 | } 45 | public static implicit operator T(Independent independent) 46 | { 47 | return independent.Value; 48 | } 49 | 50 | public override string VisualizerName(bool withValue) 51 | { 52 | string s = "[I] " + Dependent.VisualizerName(Name); 53 | if (withValue) 54 | s += " = " + (_value == null ? "null" : _value.ToString()); 55 | return s; 56 | } 57 | 58 | [Obsolete, EditorBrowsable(EditorBrowsableState.Never)] 59 | public Independent IndependentSentry 60 | { 61 | get { return this; } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /Portable/UpdateControls/IUpdatable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls 7 | { 8 | public interface IUpdatable 9 | { 10 | void UpdateNow(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Portable/UpdateControls/MemoizedTypeName.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls 7 | { 8 | /// .NET Framework reflection doesn't offer complete type names for 9 | /// generic types such as "List<int>" (the Type.Name value of that class is 10 | /// "List`1"). fills in the gap, and also saves the 11 | /// computed name for fast repeated lookups. 12 | public static class MemoizedTypeName 13 | { 14 | static Dictionary _shortNames = new Dictionary(); 15 | 16 | /// Computes a short language-agnostic name for a type, including 17 | /// generic parameters, e.g. GenericName(typeof(int)) is "Int32"; 18 | /// GenericName(typeof(Dictionary<int, string>)) is 19 | /// "Dictionary<Int32, String>". 20 | /// Type whose name you want 21 | /// Name with generic parameters, as explained in the summary. 22 | /// The result is memoized for generic types, so that the name is 23 | /// computed only once. 24 | public static string GenericName(Type type) 25 | { 26 | if (type == null) 27 | return null; 28 | string name; 29 | lock (_shortNames) 30 | { 31 | if (!_shortNames.TryGetValue(type, out name)) 32 | { 33 | if (type.IsGenericType) 34 | _shortNames[type] = name = ComputeGenericName(type); 35 | else 36 | name = type.Name; 37 | } 38 | } 39 | return name; 40 | } 41 | 42 | /// Computes a type's name without memoization. 43 | internal static string ComputeGenericName(Type type) 44 | { 45 | string result = type.Name; 46 | if (type.IsGenericType) 47 | { 48 | // remove genric indication (e.g. `1) 49 | result = result.Substring(0, result.LastIndexOf('`')); 50 | 51 | result = string.Format( 52 | "{0}<{1}>", 53 | result, 54 | string.Join(", ", type.GetGenericArguments() 55 | .Select(t => GenericName(t)).ToArray())); 56 | } 57 | return result; 58 | } 59 | 60 | /// Extension method on Type that is an alias for the method. 61 | public static string NameWithGenericParams(this Type t) 62 | { 63 | return GenericName(t); 64 | } 65 | } 66 | 67 | public static class MemoizedTypeName 68 | { 69 | static string _name; 70 | public static string GenericName() 71 | { 72 | if (_name == null) 73 | _name = MemoizedTypeName.GenericName(typeof(T)); 74 | return _name; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Portable/UpdateControls/NamedPrecedents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Diagnostics; 6 | using System.Reflection; 7 | 8 | namespace UpdateControls 9 | { 10 | public class NamedDependent : Dependent 11 | { 12 | public NamedDependent(Action update) : this(null, update) { } 13 | public NamedDependent(string name, Action update) : base(update) { _name = name; } 14 | 15 | protected string _name; 16 | public string Name 17 | { 18 | get { 19 | if (_name == null) 20 | _name = ComputeName(); 21 | return _name; 22 | } 23 | } 24 | 25 | public override string VisualizerName(bool withValue) 26 | { 27 | return VisNameWithOptionalHash(Name, withValue); 28 | } 29 | public static string GetClassAndMethodName(Delegate d) 30 | { 31 | return MemoizedTypeName.GenericName(d.Method.DeclaringType) + "." + d.Method.Name; 32 | } 33 | protected virtual string ComputeName() 34 | { 35 | return GetClassAndMethodName(_update) + "()"; 36 | } 37 | } 38 | 39 | public class NamedIndependent : Independent 40 | { 41 | public NamedIndependent() : base() { } 42 | public NamedIndependent(string name) : base() { _name = name; } 43 | public NamedIndependent(Type valueType) : this(valueType.NameWithGenericParams()) { } 44 | public NamedIndependent(Type containerType, string name) : 45 | this(string.Format("{0}.{1}", containerType.NameWithGenericParams(), name)) { } 46 | 47 | public override void OnGet() 48 | { 49 | // TODO: Figure out _name 50 | base.OnGet(); 51 | } 52 | 53 | protected string _name; 54 | public string Name 55 | { 56 | get { return _name ?? "NamedIndependent"; } 57 | set { _name = value; } 58 | } 59 | 60 | public override string VisualizerName(bool withValue) 61 | { 62 | return VisNameWithOptionalHash("[I] " + Name, withValue); 63 | } 64 | } 65 | 66 | [Obsolete] 67 | public class NamedIndependent : UpdateControls.Fields.Independent 68 | { 69 | public NamedIndependent() : base() { } 70 | public NamedIndependent(T value) : base(value) { } 71 | public NamedIndependent(string name, T value) : base(name, value) { } 72 | public NamedIndependent(Type containerType, string name) : base(containerType, name) { } 73 | public NamedIndependent(Type containerType, string name, T value) : base(containerType, name, value) { } 74 | } 75 | 76 | [Obsolete] 77 | public class NamedDependent : UpdateControls.Fields.Dependent 78 | { 79 | public NamedDependent(Func compute) : base(compute) { } 80 | public NamedDependent(string name, Func compute) : base(name, compute) { } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Portable/UpdateControls/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | [assembly: AssemblyTitle("UpdateControls")] 7 | [assembly: AssemblyProduct("UpdateControls")] 8 | -------------------------------------------------------------------------------- /Portable/UpdateControls/ThreadLocal.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | 4 | namespace UpdateControls 5 | { 6 | public class ThreadLocal 7 | { 8 | private Dictionary _valueByThread = new Dictionary(); 9 | 10 | public T Get() 11 | { 12 | lock (this) 13 | { 14 | T value; 15 | if (!_valueByThread.TryGetValue(Thread.CurrentThread.ManagedThreadId, out value)) 16 | return default(T); 17 | return value; 18 | } 19 | } 20 | 21 | public void Set(T value) 22 | { 23 | lock (this) 24 | { 25 | _valueByThread[Thread.CurrentThread.ManagedThreadId] = value; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Portable/UpdateControls/UpdateControlsExtensions.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | namespace UpdateControls 16 | { 17 | public static class UpdateControlsExtensions 18 | { 19 | /// 20 | /// Moves all objects into a new recycle bin, from which they can be extracted. 21 | /// 22 | /// A collection of objects to add to the bin. 23 | /// 24 | /// After the objects are added to the bin, the collection 25 | /// is cleared. Then it can be repopulated by extraction from 26 | /// the bin. 27 | /// 28 | public static RecycleBin Recycle(this ICollection collection) 29 | { 30 | RecycleBin bin = new RecycleBin(collection); 31 | 32 | if (collection != null) 33 | collection.Clear(); 34 | 35 | return bin; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Portable/UpdateControls/UpdateScheduler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace UpdateControls 5 | { 6 | public class UpdateScheduler 7 | { 8 | private static Action _runOnUIThread; 9 | private static ThreadLocal _currentSet = new ThreadLocal(); 10 | 11 | public static void Initialize(Action runOnUIThread) 12 | { 13 | if (_runOnUIThread == null) 14 | { 15 | _runOnUIThread = runOnUIThread; 16 | } 17 | } 18 | 19 | public static UpdateScheduler Begin() 20 | { 21 | // If someone is already capturing the affected set, 22 | // let them keep that responsibility. 23 | if (_currentSet.Get() != null) 24 | return null; 25 | 26 | UpdateScheduler currentSet = new UpdateScheduler(); 27 | _currentSet.Set(currentSet); 28 | return currentSet; 29 | } 30 | 31 | public static void ScheduleUpdate(IUpdatable updatable) 32 | { 33 | UpdateScheduler currentSet = _currentSet.Get(); 34 | if (currentSet != null) 35 | currentSet._updatables.Add(updatable); 36 | else if (_runOnUIThread != null) 37 | _runOnUIThread(updatable.UpdateNow); 38 | } 39 | 40 | private List _updatables = new List(); 41 | 42 | public IEnumerable End() 43 | { 44 | System.Diagnostics.Debug.Assert(_currentSet.Get() == this); 45 | _currentSet.Set(null); 46 | return _updatables; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("UpdateControls.XAML")] 6 | [assembly: AssemblyProduct("UpdateControls.XAML")] 7 | [assembly: ComVisible(false)] 8 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Wrapper/ClassInstance.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Linq; 15 | using System.Reflection; 16 | 17 | namespace UpdateControls.XAML.Wrapper 18 | { 19 | public class ClassInstance : DelegatedType 20 | { 21 | private Type _wrappedType; 22 | private Type _objectInstanceType; 23 | private List _classProperties; 24 | 25 | public ClassInstance(Type wrappedType, Type objectInstanceType) 26 | : base(wrappedType) 27 | { 28 | _wrappedType = wrappedType; 29 | _objectInstanceType = objectInstanceType; 30 | 31 | // Create a wrapper for each non-collection property. 32 | _classProperties = _wrappedType 33 | .GetProperties() 34 | .Select(p => new ClassProperty(p, objectInstanceType)) 35 | .ToList(); 36 | } 37 | 38 | public IEnumerable ClassProperties 39 | { 40 | get { return _classProperties; } 41 | } 42 | 43 | public override string ToString() 44 | { 45 | return _wrappedType.Name; 46 | } 47 | 48 | protected override PropertyInfo DelegatePropertyInfo(PropertyInfo rawPropertyInfo) 49 | { 50 | return new ClassProperty(rawPropertyInfo, _objectInstanceType); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Wrapper/CollectionItem.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.ObjectModel; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | class CollectionItem : IDisposable 18 | { 19 | private ObservableCollection _collection; 20 | private object _item; 21 | private bool _inCollection; 22 | 23 | public CollectionItem(ObservableCollection collection, object item, bool inCollection) 24 | { 25 | _collection = collection; 26 | _item = item; 27 | _inCollection = inCollection; 28 | } 29 | 30 | public void Dispose() 31 | { 32 | if (_inCollection) 33 | _collection.Remove(_item); 34 | } 35 | 36 | public void EnsureInCollection(int index) 37 | { 38 | if (!_inCollection) 39 | { 40 | // Insert the item into the correct position. 41 | _collection.Insert(index, _item); 42 | } 43 | else if (!object.Equals(_collection[index], _item)) 44 | { 45 | // Remove the item from the old position. 46 | _collection.Remove(_item); 47 | 48 | // Insert the item in the correct position. 49 | _collection.Insert(index, _item); 50 | } 51 | } 52 | 53 | public override int GetHashCode() 54 | { 55 | return _item.GetHashCode(); 56 | } 57 | 58 | public override bool Equals(object obj) 59 | { 60 | if (obj == null) 61 | return false; 62 | if (obj == this) 63 | return true; 64 | if (!(obj is CollectionItem)) 65 | return false; 66 | CollectionItem that = (CollectionItem)obj; 67 | return Object.Equals( 68 | this._item, 69 | that._item); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Wrapper/IObjectInstance.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Windows.Threading; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | public interface IObjectInstance 18 | { 19 | ClassInstance ClassInstance { get; } 20 | object WrappedObject { get; } 21 | Dispatcher Dispatcher { get; } 22 | ObjectProperty LookupProperty(ClassProperty classProperty); 23 | void FirePropertyChanged(string name); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Wrapper/NotificationGate.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | 14 | namespace UpdateControls.XAML.Wrapper 15 | { 16 | class NotificationGate : IDisposable 17 | { 18 | [ThreadStatic] 19 | private static int _outboundCount; 20 | 21 | private NotificationGate() 22 | { 23 | } 24 | 25 | public static bool IsInbound 26 | { 27 | get { return _outboundCount == 0; } 28 | } 29 | 30 | public static IDisposable BeginOutbound() 31 | { 32 | ++_outboundCount; 33 | return new NotificationGate(); 34 | } 35 | 36 | public void Dispose() 37 | { 38 | --_outboundCount; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Wrapper/ObjectProperty.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Windows.Threading; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | public abstract class ObjectProperty 18 | { 19 | public IObjectInstance ObjectInstance { get; private set; } 20 | public ClassProperty ClassProperty { get; private set; } 21 | 22 | public ObjectProperty(IObjectInstance objectInstance, ClassProperty classProperty) 23 | { 24 | ObjectInstance = objectInstance; 25 | ClassProperty = classProperty; 26 | } 27 | 28 | public abstract void OnUserInput(object value); 29 | public abstract object Value { get; } 30 | 31 | public static ObjectProperty From(IObjectInstance objectInstance, ClassProperty classProperty) 32 | { 33 | return classProperty.MakeObjectProperty(objectInstance); 34 | } 35 | 36 | public override string ToString() 37 | { 38 | return String.Format("{0}({1})", ClassProperty, ObjectInstance.WrappedObject); 39 | } 40 | 41 | protected object WrapObject(object value) 42 | { 43 | return typeof(ObjectInstance<>) 44 | .MakeGenericType(value.GetType()) 45 | .GetConstructor(new Type[] { typeof(object), typeof(Dispatcher) }) 46 | .Invoke(new object[] { value, ObjectInstance.Dispatcher }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Wrapper/ObjectPropertyAtomNative.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | 14 | namespace UpdateControls.XAML.Wrapper 15 | { 16 | class ObjectPropertyAtomNative : ObjectPropertyAtom 17 | { 18 | 19 | public ObjectPropertyAtomNative(IObjectInstance objectInstance, ClassProperty classProperty) 20 | : base(objectInstance, classProperty) 21 | { 22 | } 23 | public override object TranslateIncommingValue(object value) 24 | { 25 | return value; 26 | } 27 | 28 | public override object TranslateOutgoingValue(object value) 29 | { 30 | return value; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Wrapper/ObjectPropertyAtomObject.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | 14 | namespace UpdateControls.XAML.Wrapper 15 | { 16 | class ObjectPropertyAtomObject : ObjectPropertyAtom 17 | { 18 | public ObjectPropertyAtomObject(IObjectInstance objectInstance, ClassProperty classProperty) 19 | : base(objectInstance, classProperty) 20 | { 21 | } 22 | 23 | public override object TranslateIncommingValue(object value) 24 | { 25 | return value == null ? null : ((IObjectInstance)value).WrappedObject; 26 | } 27 | 28 | public override object TranslateOutgoingValue(object value) 29 | { 30 | return value == null ? null : WrapObject(value); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Wrapper/ObjectPropertyCollectionNative.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | 14 | namespace UpdateControls.XAML.Wrapper 15 | { 16 | internal class ObjectPropertyCollectionNative : ObjectPropertyCollection 17 | { 18 | public ObjectPropertyCollectionNative(IObjectInstance objectInstance, ClassProperty classProperty) 19 | : base(objectInstance, classProperty) 20 | { 21 | } 22 | 23 | public override object TranslateOutgoingValue(object value) 24 | { 25 | return value; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Silverlight/UpdateControls.XAML/Wrapper/ObjectPropertyCollectionObject.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | 14 | namespace UpdateControls.XAML.Wrapper 15 | { 16 | internal class ObjectPropertyCollectionObject : ObjectPropertyCollection 17 | { 18 | public ObjectPropertyCollectionObject(IObjectInstance objectInstance, ClassProperty classProperty) 19 | : base(objectInstance, classProperty) 20 | { 21 | } 22 | 23 | public override object TranslateOutgoingValue(object value) 24 | { 25 | return value == null ? null : WrapObject(value); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/ContactList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UpdateControls; 4 | 5 | namespace UpdateControls.Test 6 | { 7 | public class ContactList 8 | { 9 | private List _people = new List(); 10 | 11 | #region Independent properties 12 | // Generated by Update Controls -------------------------------- 13 | private Independent _indPeople = new Independent(); 14 | 15 | public Person NewPerson() 16 | { 17 | _indPeople.OnSet(); 18 | Person person = new Person(); 19 | _people.Add(person); 20 | return person; 21 | } 22 | 23 | public void DeletePerson(Person person) 24 | { 25 | _indPeople.OnSet(); 26 | _people.Remove(person); 27 | } 28 | 29 | public IEnumerable People 30 | { 31 | get { _indPeople.OnGet(); return _people; } 32 | } 33 | // End generated code -------------------------------- 34 | #endregion 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/ContactListNavigationModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UpdateControls; 3 | 4 | namespace UpdateControls.Test 5 | { 6 | public class ContactListNavigationModel 7 | { 8 | private Person _selectedPerson; 9 | 10 | #region Independent properties 11 | // Generated by Update Controls -------------------------------- 12 | private Independent _indSelectedPerson = new Independent(); 13 | 14 | public Person SelectedPerson 15 | { 16 | get { _indSelectedPerson.OnGet(); return _selectedPerson; } 17 | set { _indSelectedPerson.OnSet(); _selectedPerson = value; } 18 | } 19 | // End generated code -------------------------------- 20 | #endregion 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/ContactListViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Input; 5 | using UpdateControls.Fields; 6 | using UpdateControls.XAML; 7 | 8 | namespace UpdateControls.Test 9 | { 10 | public class ContactListViewModel 11 | { 12 | private ContactList _contactList; 13 | private ContactListNavigationModel _navigation; 14 | 15 | private static List _prefixes = 16 | new List 17 | { 18 | new PrefixViewModel(PrefixID.None), 19 | new PrefixViewModel(PrefixID.Mr), 20 | new PrefixViewModel(PrefixID.Mrs), 21 | new PrefixViewModel(PrefixID.Miss), 22 | new PrefixViewModel(PrefixID.Dr) 23 | }; 24 | 25 | public static IEnumerable AllPrefixes { get { return _prefixes; } } 26 | 27 | public ContactListViewModel(ContactList contactList, ContactListNavigationModel navigation) 28 | { 29 | _contactList = contactList; 30 | _navigation = navigation; 31 | } 32 | 33 | public IEnumerable People 34 | { 35 | get { return _contactList.People.Select(p => PersonViewModel.Wrap(p, _contactList)); } 36 | } 37 | 38 | public PersonViewModel SelectedPerson 39 | { 40 | get { return PersonViewModel.Wrap(_navigation.SelectedPerson, _contactList); } 41 | set { _navigation.SelectedPerson = PersonViewModel.Unwrap(value); } 42 | } 43 | 44 | public bool IsPersonSelected 45 | { 46 | get { return _navigation.SelectedPerson != null; } 47 | } 48 | 49 | public IEnumerable Prefixes 50 | { 51 | get { return _prefixes; } 52 | } 53 | 54 | public IEnumerable GenderOptions 55 | { 56 | get 57 | { 58 | yield return GenderEnum.Male; 59 | yield return GenderEnum.Female; 60 | } 61 | } 62 | 63 | public System.Windows.Input.ICommand NewPerson 64 | { 65 | get 66 | { 67 | return MakeCommand 68 | .Do(() => _navigation.SelectedPerson = _contactList.NewPerson()); 69 | } 70 | } 71 | 72 | public ICommand DeletePerson 73 | { 74 | get 75 | { 76 | return MakeCommand 77 | .When(() => _navigation.SelectedPerson != null) 78 | .Do(() => _contactList.DeletePerson(_navigation.SelectedPerson)); 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/GenderEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace UpdateControls.Test 4 | { 5 | public enum GenderEnum 6 | { 7 | Male, 8 | Female 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/GenderOption.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls.Test 7 | { 8 | public class GenderOption 9 | { 10 | private readonly GenderEnum _gender; 11 | 12 | public GenderOption(GenderEnum gender) 13 | { 14 | _gender = gender; 15 | } 16 | 17 | public GenderEnum Gender 18 | { 19 | get { return _gender; } 20 | } 21 | 22 | public override string ToString() 23 | { 24 | return _gender.ToString(); 25 | } 26 | 27 | public override bool Equals(object obj) 28 | { 29 | if (obj == this) 30 | return true; 31 | GenderOption that = obj as GenderOption; 32 | if (that == null) 33 | return false; 34 | return Object.Equals(this._gender, that._gender); 35 | } 36 | 37 | public override int GetHashCode() 38 | { 39 | return _gender.GetHashCode(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/ISpouseViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace UpdateControls.Test 4 | { 5 | public interface ISpouseViewModel 6 | { 7 | Person Spouse { get; } 8 | string FullName { get; } 9 | bool Equals(object obj); 10 | int GetHashCode(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UpdateControls; 3 | 4 | namespace UpdateControls.Test 5 | { 6 | public class Person 7 | { 8 | private PrefixID _prefix; 9 | private string _first; 10 | private string _last; 11 | private GenderEnum _gender; 12 | private Person _spouse; 13 | 14 | #region Independent properties 15 | // Generated by Update Controls -------------------------------- 16 | private Independent _indPrefix = new Independent(); 17 | private Independent _indFirst = new Independent(); 18 | private Independent _indLast = new Independent(); 19 | private Independent _indGender = new Independent(); 20 | private Independent _indSpouse = new Independent(); 21 | 22 | public PrefixID Prefix 23 | { 24 | get { _indPrefix.OnGet(); return _prefix; } 25 | set { _indPrefix.OnSet(); _prefix = value; } 26 | } 27 | 28 | public string First 29 | { 30 | get { _indFirst.OnGet(); return _first; } 31 | set { _indFirst.OnSet(); _first = value; } 32 | } 33 | 34 | public string Last 35 | { 36 | get { _indLast.OnGet(); return _last; } 37 | set { _indLast.OnSet(); _last = value; } 38 | } 39 | 40 | public GenderEnum Gender 41 | { 42 | get { _indGender.OnGet(); return _gender; } 43 | set { _indGender.OnSet(); _gender = value; } 44 | } 45 | 46 | public Person Spouse 47 | { 48 | get { _indSpouse.OnGet(); return _spouse; } 49 | private set { _indSpouse.OnSet(); _spouse = value; } 50 | } 51 | // End generated code -------------------------------- 52 | #endregion 53 | 54 | public string FullName 55 | { 56 | get 57 | { 58 | return string.Format("{0}{1} {2}", 59 | Prefix == PrefixID.Mr ? "Mr. " : 60 | Prefix == PrefixID.Mrs ? "Mrs. " : 61 | Prefix == PrefixID.Miss ? "Miss " : 62 | Prefix == PrefixID.Dr ? "Dr. " : 63 | "", 64 | First, 65 | Last); 66 | } 67 | } 68 | 69 | public static void Marry(Person a, Person b) 70 | { 71 | // If either person is already married, 72 | // annul that marriage. 73 | if (a != null && a.Spouse != null) 74 | { 75 | a.Spouse.Spouse = null; 76 | a.Spouse = null; 77 | } 78 | 79 | if (b != null && b.Spouse != null) 80 | { 81 | b.Spouse.Spouse = null; 82 | b.Spouse = null; 83 | } 84 | 85 | // Marry the two people 86 | if (a != null && b != null) 87 | { 88 | a.Spouse = b; 89 | b.Spouse = a; 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/PersonViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace UpdateControls.Test 6 | { 7 | public class PersonViewModel : PersonViewModelBase 8 | { 9 | private ContactList _contactList; 10 | 11 | public PersonViewModel(Person person, ContactList contactList) 12 | : base(person) 13 | { 14 | _contactList = contactList; 15 | } 16 | 17 | public IEnumerable PotentialSpouses 18 | { 19 | get 20 | { 21 | return 22 | // Return all people of the opposite gender. 23 | // Include an option to be unmarried. 24 | new List() { null } 25 | .Union(_contactList.People 26 | .Where(p => p.Gender != Person.Gender) 27 | ) 28 | .Select(p => (ISpouseViewModel)SpouseViewModel.Wrap(p)); 29 | } 30 | } 31 | 32 | public static PersonViewModel Wrap(Person person, ContactList contactList) 33 | { 34 | if (person == null) 35 | return null; 36 | else 37 | return new PersonViewModel(person, contactList); 38 | } 39 | 40 | public static Person Unwrap(PersonViewModel viewModel) 41 | { 42 | if (viewModel == null) 43 | return null; 44 | else 45 | return viewModel.Person; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/PersonViewModelBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | 5 | namespace UpdateControls.Test 6 | { 7 | public class PersonViewModelBase 8 | { 9 | private Person _person; 10 | 11 | public PersonViewModelBase(Person person) 12 | { 13 | _person = person; 14 | } 15 | 16 | public Person Person 17 | { 18 | get { return _person; } 19 | } 20 | 21 | public PrefixViewModel Prefix 22 | { 23 | get { return ContactListViewModel.AllPrefixes.First(p => p.Prefix == _person.Prefix); } 24 | set { _person.Prefix = value.Prefix; } 25 | } 26 | 27 | public string First 28 | { 29 | get { return _person.First; } 30 | set { _person.First = value.Trim(); } 31 | } 32 | 33 | public string Last 34 | { 35 | get { return _person.Last; } 36 | set { _person.Last = value.Trim(); } 37 | } 38 | 39 | public string FullName 40 | { 41 | get { return _person.FullName; } 42 | } 43 | 44 | public GenderEnum Gender 45 | { 46 | get { return _person.Gender; } 47 | set { _person.Gender = value; } 48 | } 49 | 50 | public ISpouseViewModel Spouse 51 | { 52 | get { return SpouseViewModel.Wrap(_person.Spouse); } 53 | set { if (value != null) Person.Marry(_person, value.Spouse); } 54 | } 55 | 56 | public override bool Equals(object obj) 57 | { 58 | if (obj == this) 59 | return true; 60 | PersonViewModel that = obj as PersonViewModel; 61 | if (that == null) 62 | return false; 63 | return Object.Equals(this._person, that._person); 64 | } 65 | 66 | public override int GetHashCode() 67 | { 68 | return _person.GetHashCode(); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/PrefixID.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace UpdateControls.Test 4 | { 5 | public enum PrefixID 6 | { 7 | None, 8 | Mr, 9 | Mrs, 10 | Miss, 11 | Dr 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/PrefixViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace UpdateControls.Test 4 | { 5 | public class PrefixViewModel 6 | { 7 | private PrefixID _prefix; 8 | 9 | public PrefixViewModel(PrefixID prefix) 10 | { 11 | _prefix = prefix; 12 | } 13 | 14 | public PrefixID Prefix 15 | { 16 | get { return _prefix; } 17 | } 18 | 19 | public override string ToString() 20 | { 21 | return _prefix.ToString(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("UpdateControls.Test")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("UpdateControls.Test")] 14 | [assembly: AssemblyCopyright("Copyright © 2012")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: NeutralResourcesLanguage("en")] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /Universal/UpdateControls.Test/SpouseViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace UpdateControls.Test 4 | { 5 | public class SpouseViewModel : ISpouseViewModel 6 | { 7 | private Person _spouse; 8 | 9 | private SpouseViewModel(Person spouse) 10 | { 11 | _spouse = spouse; 12 | } 13 | 14 | public Person Spouse 15 | { 16 | get { return _spouse; } 17 | } 18 | 19 | public string FullName 20 | { 21 | get { return _spouse == null ? "unmarried" : _spouse.FullName; } 22 | } 23 | 24 | public override bool Equals(object obj) 25 | { 26 | if (obj == this) 27 | return true; 28 | SpouseViewModel that = obj as SpouseViewModel; 29 | if (that == null) 30 | return false; 31 | return object.Equals(this._spouse, that._spouse); 32 | } 33 | 34 | public override int GetHashCode() 35 | { 36 | return _spouse == null ? 0 : _spouse.GetHashCode(); 37 | } 38 | 39 | public static SpouseViewModel Wrap(Person spouse) 40 | { 41 | return new SpouseViewModel(spouse); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Universal/UpdateControls.XAML/ForView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UpdateControls.XAML.Wrapper; 3 | using Windows.UI.Core; 4 | using Windows.UI.Xaml; 5 | 6 | namespace UpdateControls.XAML 7 | { 8 | public static class ForView 9 | { 10 | private static CoreDispatcher _mainDispatcher; 11 | 12 | public static void Initialize() 13 | { 14 | // Ensure that the UpdateScheduler has the ability to run delegates 15 | // on the UI thread. 16 | if (_mainDispatcher == null) 17 | { 18 | _mainDispatcher = Window.Current.Dispatcher; 19 | } 20 | UpdateScheduler.Initialize(RunOnUIThread); 21 | } 22 | 23 | public static object Wrap(object viewModel) 24 | { 25 | Initialize(); 26 | if (viewModel == null) 27 | return null; 28 | return (IObjectInstance)Activator.CreateInstance( 29 | typeof(ObjectInstance<>).MakeGenericType(viewModel.GetType()), 30 | viewModel); 31 | } 32 | 33 | public static TWrappedObjectType Unwrap(object dataContext) 34 | where TWrappedObjectType : class 35 | { 36 | IObjectInstance wrapper = dataContext as IObjectInstance; 37 | return 38 | wrapper == null 39 | ? default(TWrappedObjectType) 40 | : wrapper.WrappedObject as TWrappedObjectType; 41 | } 42 | 43 | private static async void RunOnUIThread(Action action) 44 | { 45 | if (_mainDispatcher != null) 46 | { 47 | await _mainDispatcher.RunAsync( 48 | CoreDispatcherPriority.Low, 49 | new DispatchedHandler(delegate 50 | { 51 | action(); 52 | })); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Universal/UpdateControls.XAML/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("UpdateControls.XAML")] 6 | [assembly: AssemblyProduct("UpdateControls.XAML")] 7 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /Universal/UpdateControls.XAML/ViewModelLocatorBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Runtime.CompilerServices; 5 | 6 | namespace UpdateControls.XAML 7 | { 8 | public class ViewModelLocatorBase : INotifyPropertyChanged 9 | { 10 | private class ViewModelContainer : IUpdatable 11 | { 12 | private Dependent _dependent; 13 | private object _viewModel; 14 | private Action _firePropertyChanged; 15 | 16 | public ViewModelContainer(Action firePropertyChanged, Func constructor) 17 | { 18 | _firePropertyChanged = firePropertyChanged; 19 | _dependent = new Dependent(() => _viewModel = ForView.Wrap(constructor())); 20 | _dependent.Invalidated += () => UpdateScheduler.ScheduleUpdate(this); 21 | } 22 | 23 | public object ViewModel 24 | { 25 | get { _dependent.OnGet(); return _viewModel; } 26 | } 27 | 28 | public void UpdateNow() 29 | { 30 | _firePropertyChanged(); 31 | } 32 | } 33 | 34 | public event PropertyChangedEventHandler PropertyChanged; 35 | 36 | private IDictionary _containerByName = new Dictionary(); 37 | 38 | private readonly bool _designMode; 39 | 40 | public ViewModelLocatorBase() 41 | { 42 | _designMode = Windows.ApplicationModel.DesignMode.DesignModeEnabled; 43 | } 44 | 45 | public bool DesignMode 46 | { 47 | get { return _designMode; } 48 | } 49 | 50 | public object ViewModel(Func constructor, [CallerMemberName] string propertyName = "") 51 | { 52 | if (DesignMode) 53 | return constructor(); 54 | 55 | ForView.Initialize(); 56 | ViewModelContainer container; 57 | if (!_containerByName.TryGetValue(propertyName, out container)) 58 | { 59 | container = new ViewModelContainer(() => FirePropertyChanged(propertyName), constructor); 60 | _containerByName.Add(propertyName, container); 61 | } 62 | return container.ViewModel; 63 | } 64 | 65 | private void FirePropertyChanged(string propertyName) 66 | { 67 | if (PropertyChanged != null) 68 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Universal/UpdateControls.XAML/Wrapper/CollectionItem.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.ObjectModel; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | class CollectionItem : IDisposable 18 | { 19 | private ObservableCollection _collection; 20 | private object _item; 21 | private bool _inCollection; 22 | 23 | public CollectionItem(ObservableCollection collection, object item, bool inCollection) 24 | { 25 | _collection = collection; 26 | _item = item; 27 | _inCollection = inCollection; 28 | } 29 | 30 | public void Dispose() 31 | { 32 | if (_inCollection) 33 | _collection.Remove(_item); 34 | } 35 | 36 | public void EnsureInCollection(int index) 37 | { 38 | if (!_inCollection) 39 | { 40 | // Insert the item into the correct position. 41 | _collection.Insert(index, _item); 42 | } 43 | else if (!object.Equals(_collection[index], _item)) 44 | { 45 | // Remove the item from the old position. 46 | _collection.Remove(_item); 47 | 48 | // Insert the item in the correct position. 49 | _collection.Insert(index, _item); 50 | } 51 | } 52 | 53 | public override int GetHashCode() 54 | { 55 | return _item.GetHashCode(); 56 | } 57 | 58 | public override bool Equals(object obj) 59 | { 60 | if (obj == null) 61 | return false; 62 | if (obj == this) 63 | return true; 64 | if (!(obj is CollectionItem)) 65 | return false; 66 | CollectionItem that = (CollectionItem)obj; 67 | return Object.Equals( 68 | this._item, 69 | that._item); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Universal/UpdateControls.XAML/Wrapper/CustomMetadataProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.UI.Xaml.Markup; 7 | 8 | namespace UpdateControls.XAML.Wrapper 9 | { 10 | public class CustomMetadataProvider : IXamlMetadataProvider 11 | { 12 | private static Dictionary _xamlTypeFromCLR = new Dictionary(); 13 | 14 | public IXamlType GetXamlType(string fullName) 15 | { 16 | return null; 17 | } 18 | 19 | public IXamlType GetXamlType(Type type) 20 | { 21 | if (type.IsConstructedGenericType) 22 | { 23 | if (type.GetGenericTypeDefinition() == typeof(ObjectInstance<>)) 24 | { 25 | Type wrappedType = type.GenericTypeArguments[0]; 26 | return GetDependentType(wrappedType); 27 | } 28 | } 29 | return null; 30 | } 31 | 32 | public static IXamlType GetDependentType(Type wrappedType) 33 | { 34 | lock (_xamlTypeFromCLR) 35 | { 36 | IXamlType xamlType; 37 | if (!_xamlTypeFromCLR.TryGetValue(wrappedType, out xamlType)) 38 | { 39 | xamlType = new CustomTypeProvider(wrappedType); 40 | _xamlTypeFromCLR.Add(wrappedType, xamlType); 41 | } 42 | return xamlType; 43 | } 44 | } 45 | 46 | public XmlnsDefinition[] GetXmlnsDefinitions() 47 | { 48 | return null; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Universal/UpdateControls/Collections/DependentList.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2011 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | namespace UpdateControls.Collections 16 | { 17 | public class DependentList : IEnumerable 18 | { 19 | private readonly Func> _computeCollection; 20 | 21 | private List _list = new List(); 22 | private Dependent _dependentSentry; 23 | 24 | public DependentList(Func> computeCollection) 25 | { 26 | _computeCollection = computeCollection; 27 | 28 | _dependentSentry = new Dependent( 29 | delegate { 30 | using (var bin = new RecycleBin(_list)) 31 | { 32 | _list.Clear(); 33 | 34 | foreach (T item in computeCollection()) 35 | _list.Add(bin.Extract(item)); 36 | } 37 | }); 38 | } 39 | 40 | public int IndexOf(T item) 41 | { 42 | _dependentSentry.OnGet(); 43 | return _list.IndexOf(item); 44 | } 45 | 46 | public T this[int index] 47 | { 48 | get 49 | { 50 | _dependentSentry.OnGet(); 51 | return _list[index]; 52 | } 53 | } 54 | 55 | public bool Contains(T item) 56 | { 57 | _dependentSentry.OnGet(); 58 | return _list.Contains(item); 59 | } 60 | 61 | public void CopyTo(T[] array, int arrayIndex) 62 | { 63 | _dependentSentry.OnGet(); 64 | _list.CopyTo(array, arrayIndex); 65 | } 66 | 67 | public int Count 68 | { 69 | get { _dependentSentry.OnGet(); return _list.Count; } 70 | } 71 | 72 | public IEnumerator GetEnumerator() 73 | { 74 | _dependentSentry.OnGet(); 75 | return _list.GetEnumerator(); 76 | } 77 | 78 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 79 | { 80 | _dependentSentry.OnGet(); 81 | return ((System.Collections.IEnumerable)_list).GetEnumerator(); 82 | } 83 | 84 | public Dependent DependentSentry 85 | { 86 | get { return _dependentSentry; } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Universal/UpdateControls/Collections/Impl/UpdateCollectionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls.Collections.Impl 7 | { 8 | /// Helper structure used by DependentDictionary and 9 | /// IndependentDictionary to represent the "Keys" and "Values" members. 10 | /// 11 | /// If you save a reference to the Keys or Values property of , 12 | /// the independent sentry should be informed when that collection is accessed. 13 | /// This helper class ensures that the sentry is notified. 14 | /// 15 | /// For , this class is even more 16 | /// important. Whenever DependentDictionary is updated, a new dictionary is 17 | /// created to hold the updated content, so the Keys and Values collections 18 | /// change frequently. This wrapper ensure that you do not accidentally hold 19 | /// a reference to an out-of-date version of the Keys or Values collection. 20 | /// It also ensures that the dictionary is updated if necessary when it is 21 | /// accessed through the Keys or Values collection. 22 | /// 23 | public struct UpdateCollectionHelper : ICollection 24 | { 25 | readonly Func> _get; 26 | 27 | public UpdateCollectionHelper(Func> getCollection) 28 | { 29 | _get = getCollection; 30 | } 31 | 32 | public void Add(T item) 33 | { 34 | throw new NotSupportedException(); 35 | } 36 | public void Clear() 37 | { 38 | throw new NotSupportedException(); 39 | } 40 | public bool Contains(T item) 41 | { 42 | return _get().Contains(item); 43 | } 44 | public void CopyTo(T[] array, int arrayIndex) 45 | { 46 | _get().CopyTo(array, arrayIndex); 47 | } 48 | public int Count 49 | { 50 | get { return _get().Count; } 51 | } 52 | public bool IsReadOnly 53 | { 54 | get { return true; } 55 | } 56 | public bool Remove(T item) 57 | { 58 | throw new NotSupportedException(); 59 | } 60 | 61 | public IEnumerator GetEnumerator() 62 | { 63 | return _get().GetEnumerator(); 64 | } 65 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 66 | { 67 | return GetEnumerator(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Universal/UpdateControls/Fields/Dependent.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2011 Michael L Perry 5 | * MIT License 6 | * 7 | * This class based on a contribution by David Piepgrass. 8 | * 9 | * http://updatecontrols.net 10 | * http://www.codeplex.com/updatecontrols/ 11 | * 12 | **********************************************************************/ 13 | 14 | using System; 15 | using System.ComponentModel; 16 | 17 | namespace UpdateControls.Fields 18 | { 19 | public class Dependent : Dependent 20 | { 21 | protected internal T _value; 22 | protected Func _computeValue; 23 | 24 | public Dependent(Func compute) : base(null) 25 | { 26 | base._update = Update; _computeValue = compute; 27 | } 28 | 29 | protected void Update() 30 | { 31 | _value = _computeValue(); 32 | // TODO: don't propagate updates when _value did not change. 33 | // T oldValue = _value; 34 | // _value = _computeValue(); 35 | // return _value == null ? oldValue != null : !_value.Equals(oldValue); 36 | } 37 | 38 | public T Value 39 | { 40 | get { base.OnGet(); return _value; } 41 | } 42 | public static implicit operator T(Dependent dependent) 43 | { 44 | return dependent.Value; 45 | } 46 | 47 | public override string VisualizerName(bool withValue) 48 | { 49 | string s = String.Format("Dependent<{0}>", typeof(T).Name); 50 | if (withValue) 51 | s += " = " + (_value == null ? "null" : _value.ToString()); 52 | return s; 53 | } 54 | 55 | [Obsolete, EditorBrowsable(EditorBrowsableState.Never)] 56 | public Dependent DependentSentry 57 | { 58 | get { return this; } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Universal/UpdateControls/Fields/Independent.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2011 Michael L Perry 5 | * MIT License 6 | * 7 | * This class based on a contribution by David Piepgrass. 8 | * 9 | * http://updatecontrols.net 10 | * http://www.codeplex.com/updatecontrols/ 11 | * 12 | **********************************************************************/ 13 | using System; 14 | using System.ComponentModel; 15 | 16 | namespace UpdateControls.Fields 17 | { 18 | public class Independent : Independent 19 | { 20 | protected internal T _value; 21 | 22 | public Independent() { } 23 | public Independent(T value) { _value = value; } 24 | 25 | public T Value 26 | { 27 | get { base.OnGet(); return _value; } 28 | set { 29 | if (_value == null ? value != null : !_value.Equals(value)) 30 | { 31 | base.OnSet(); 32 | _value = value; 33 | } 34 | } 35 | } 36 | public static implicit operator T(Independent independent) 37 | { 38 | return independent.Value; 39 | } 40 | 41 | public override string VisualizerName(bool withValue) 42 | { 43 | string s = String.Format("Independent<{0}>", typeof(T).Name); 44 | if (withValue) 45 | s += " = " + (_value == null ? "null" : _value.ToString()); 46 | return s; 47 | } 48 | 49 | [Obsolete, EditorBrowsable(EditorBrowsableState.Never)] 50 | public Independent IndependentSentry 51 | { 52 | get { return this; } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Universal/UpdateControls/IUpdatable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls 7 | { 8 | public interface IUpdatable 9 | { 10 | void UpdateNow(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Universal/UpdateControls/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | [assembly: AssemblyTitle("UpdateControls")] 7 | [assembly: AssemblyProduct("UpdateControls")] 8 | -------------------------------------------------------------------------------- /Universal/UpdateControls/UpdateControlsExtensions.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | namespace UpdateControls 16 | { 17 | public static class UpdateControlsExtensions 18 | { 19 | /// 20 | /// Moves all objects into a new recycle bin, from which they can be extracted. 21 | /// 22 | /// A collection of objects to add to the bin. 23 | /// 24 | /// After the objects are added to the bin, the collection 25 | /// is cleared. Then it can be repopulated by extraction from 26 | /// the bin. 27 | /// 28 | public static RecycleBin Recycle(this ICollection collection) 29 | { 30 | RecycleBin bin = new RecycleBin(collection); 31 | 32 | if (collection != null) 33 | collection.Clear(); 34 | 35 | return bin; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Universal/UpdateControls/UpdateScheduler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | 5 | namespace UpdateControls 6 | { 7 | public class UpdateScheduler 8 | { 9 | private static Action _runOnUIThread; 10 | private static ThreadLocal _currentSet = new ThreadLocal(); 11 | 12 | public static void Initialize(Action runOnUIThread) 13 | { 14 | if (_runOnUIThread == null) 15 | { 16 | _runOnUIThread = runOnUIThread; 17 | } 18 | } 19 | 20 | public static UpdateScheduler Begin() 21 | { 22 | // If someone is already capturing the affected set, 23 | // let them keep that responsibility. 24 | if (_currentSet.Value != null) 25 | return null; 26 | 27 | UpdateScheduler currentSet = new UpdateScheduler(); 28 | _currentSet.Value = currentSet; 29 | return currentSet; 30 | } 31 | 32 | public static void ScheduleUpdate(IUpdatable updatable) 33 | { 34 | UpdateScheduler currentSet = _currentSet.Value; 35 | if (currentSet != null) 36 | currentSet._updatables.Add(updatable); 37 | else if (_runOnUIThread != null) 38 | _runOnUIThread(updatable.UpdateNow); 39 | } 40 | 41 | private List _updatables = new List(); 42 | 43 | public IEnumerable End() 44 | { 45 | System.Diagnostics.Debug.Assert(_currentSet.Value == this); 46 | _currentSet.Value = null; 47 | return _updatables; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/BindingInterceptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using UpdateControls.XAML.Wrapper; 8 | 9 | namespace UpdateControls.XAML 10 | { 11 | public class BindingInterceptor 12 | { 13 | public static BindingInterceptor Current = new BindingInterceptor(); 14 | 15 | public virtual object GetValue(ObjectProperty property) { return property.ContinueGetValue(); } 16 | public virtual void SetValue(ObjectProperty property, object value) { property.ContinueSetValue(value); } 17 | public virtual void UpdateValue(ObjectProperty property) { property.ContinueUpdateValue(); } 18 | public virtual void Execute(ObjectPropertyCommand command) { command.ContinueExecute(); } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("UpdateControls.XAML")] 6 | [assembly: AssemblyProduct("UpdateControls.XAML")] 7 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Timers/FloatingTimeSpan.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 UpdateControls.Timers 8 | { 9 | public abstract class FloatingTimeSpan 10 | { 11 | protected readonly FloatingTimeZone _zone; 12 | protected readonly DateTime _zero; 13 | 14 | public FloatingTimeZone Zone { get { return _zone; } } 15 | public DateTime ZeroMoment { get { return _zero; } } 16 | public abstract TimeSpan Snapshot { get; } 17 | public int Days { get { return GetComponent(Snapshot.Days, new TimeSpan(Snapshot.Days, 0, 0, 0), TimeSpan.FromDays(1)); } } 18 | public int Hours { get { return GetComponent(Snapshot.Hours, new TimeSpan(Snapshot.Days, Snapshot.Hours, 0, 0), TimeSpan.FromHours(1)); } } 19 | public int Minutes { get { return GetComponent(Snapshot.Minutes, new TimeSpan(Snapshot.Days, Snapshot.Hours, Snapshot.Minutes, 0), TimeSpan.FromMinutes(1)); } } 20 | public int Seconds { get { return GetComponent(Snapshot.Seconds, new TimeSpan(Snapshot.Days, Snapshot.Hours, Snapshot.Minutes, Snapshot.Seconds), TimeSpan.FromSeconds(1)); } } 21 | 22 | protected abstract int GetComponent(int component, TimeSpan cut, TimeSpan increment); 23 | 24 | protected FloatingTimeSpan(FloatingTimeZone zone, DateTime zero) 25 | { 26 | _zone = zone; 27 | _zero = zero; 28 | } 29 | 30 | public override string ToString() { return Snapshot.ToString(); } 31 | 32 | protected void CheckZone(FloatingTimeSpan other) 33 | { 34 | if (_zone != other._zone) 35 | throw new ArgumentException("Cannot relate FloatingTimeSpan instances from two different time zones"); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Timers/IndependentTimer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows.Threading; 6 | 7 | namespace UpdateControls.Timers 8 | { 9 | public class IndependentTimer : Independent 10 | { 11 | FloatingTimeZone _zone; 12 | DateTime _time; 13 | bool _expired; 14 | 15 | public DateTime ExpirationTime { get { return _time; } } 16 | 17 | public bool IsExpired 18 | { 19 | get 20 | { 21 | OnGet(); 22 | return _expired; 23 | } 24 | } 25 | 26 | internal IndependentTimer(FloatingTimeZone zone, DateTime time) 27 | { 28 | _zone = zone; 29 | _time = time; 30 | _expired = _zone.GetStableTime() >= time; 31 | } 32 | 33 | public static IndependentTimer Get(FloatingTimeZone zone, DateTime time) 34 | { 35 | return zone.GetTimer(time); 36 | } 37 | 38 | public static IndependentTimer GetUtc(DateTime utc) 39 | { 40 | return FloatingTimeZone.Utc.GetTimer(utc); 41 | } 42 | 43 | protected override void GainDependent() 44 | { 45 | _zone.Enqueue(this, _expired); 46 | } 47 | 48 | protected override void LoseDependent() 49 | { 50 | _zone.Dequeue(this); 51 | } 52 | 53 | internal void Expire(bool expire) 54 | { 55 | if (_expired != expire) 56 | { 57 | _expired = expire; 58 | OnSet(); 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Timers/UtcTimeZone.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.Threading; 7 | 8 | namespace UpdateControls.Timers 9 | { 10 | class UtcTimeZone : FloatingTimeZone 11 | { 12 | DispatcherTimer _timer = new DispatcherTimer(); 13 | 14 | public UtcTimeZone() { _timer.Tick += Expire; } 15 | 16 | public override DateTime GetRawTime() { return DateTime.UtcNow; } 17 | 18 | protected override void ScheduleTimer(TimeSpan delay) 19 | { 20 | _timer.Stop(); 21 | _timer.Interval = new TimeSpan(Math.Max(TimeSpan.FromMilliseconds(20).Ticks, delay.Ticks)); 22 | _timer.Start(); 23 | } 24 | 25 | protected override void CancelTimer() 26 | { 27 | _timer.Stop(); 28 | } 29 | 30 | void Expire(object sender, EventArgs args) 31 | { 32 | _timer.Stop(); 33 | NotifyTimerExpired(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ClassEvent.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.ComponentModel; 14 | using System.Reflection; 15 | 16 | namespace UpdateControls.XAML.Wrapper 17 | { 18 | public class ClassEvent : EventDescriptor 19 | { 20 | private EventInfo _eventInfo; 21 | 22 | public ClassEvent(EventInfo eventInfo) 23 | : base(eventInfo.Name, null) 24 | { 25 | _eventInfo = eventInfo; 26 | } 27 | 28 | public override void AddEventHandler(object component, Delegate value) 29 | { 30 | // Add the event handler to the wrapped object. 31 | _eventInfo.AddEventHandler(GetTarget(component), value); 32 | } 33 | 34 | public override void RemoveEventHandler(object component, Delegate value) 35 | { 36 | // Remove the event handler from the wrapped object. 37 | _eventInfo.RemoveEventHandler(GetTarget(component), value); 38 | } 39 | 40 | public override Type ComponentType 41 | { 42 | get { return _eventInfo.DeclaringType; } 43 | } 44 | 45 | public override Type EventType 46 | { 47 | get { return _eventInfo.EventHandlerType; } 48 | } 49 | 50 | public override bool IsMulticast 51 | { 52 | get { return _eventInfo.IsMulticast; } 53 | } 54 | 55 | private static object GetTarget(object component) 56 | { 57 | return ((IObjectInstance)component).WrappedObject; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ClassInstanceProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Reflection; 4 | 5 | namespace UpdateControls.XAML.Wrapper 6 | { 7 | public class ClassInstanceProvider : TypeDescriptionProvider 8 | { 9 | public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) 10 | { 11 | IObjectInstance objectInstance = instance as IObjectInstance; 12 | if (objectInstance != null) 13 | return objectInstance.ClassInstance; 14 | 15 | if (objectType.IsGenericType) 16 | { 17 | var genericRoot = objectType.GetGenericTypeDefinition(); 18 | if (genericRoot == typeof(ObjectInstance<>)) 19 | { 20 | var field = objectType.GetField("_classInstance", 21 | BindingFlags.NonPublic | 22 | BindingFlags.Static | 23 | BindingFlags.DeclaredOnly); 24 | var value = field.GetValue(null); 25 | return value as ICustomTypeDescriptor; 26 | } 27 | } 28 | 29 | return new ClassInstance(objectType, typeof(ObjectInstance<>).MakeGenericType(objectType)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ClassMemberCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Input; 8 | 9 | namespace UpdateControls.XAML.Wrapper 10 | { 11 | public class ClassMemberCommand : ClassMember 12 | { 13 | public MethodInfo ExecuteMethod { get; private set; } 14 | public ClassMember CanExecuteProperty { get; private set; } 15 | 16 | public ClassMemberCommand(MethodInfo method, ClassMember condition, Type objectInstanceType) 17 | : base(method.Name, typeof(ObjectPropertyCommand), objectInstanceType) 18 | { 19 | ExecuteMethod = method; 20 | CanExecuteProperty = condition; 21 | } 22 | 23 | public override object GetObjectValue(object wrappedObject) { return null; } 24 | public override void SetObjectValue(object wrappedObject, object value) { } 25 | 26 | public override bool CanRead 27 | { 28 | get { return true; } 29 | } 30 | 31 | public override Type UnderlyingType 32 | { 33 | get { return typeof(ObjectPropertyCommand); } 34 | } 35 | 36 | public override bool IsReadOnly 37 | { 38 | get { return true; } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ClassMemberField.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace UpdateControls.XAML.Wrapper 9 | { 10 | public class ClassMemberField : ClassMember 11 | { 12 | private FieldInfo _fieldInfo; 13 | 14 | public ClassMemberField(FieldInfo field, Type objectInstanceType) 15 | : base(field.Name, field.FieldType, objectInstanceType) 16 | { 17 | _fieldInfo = field; 18 | } 19 | 20 | public override object GetObjectValue(object wrappedObject) 21 | { 22 | return _fieldInfo.GetValue(wrappedObject); 23 | } 24 | 25 | public override void SetObjectValue(object wrappedObject, object value) 26 | { 27 | _fieldInfo.SetValue(wrappedObject, value); 28 | } 29 | 30 | public override bool CanRead 31 | { 32 | get { return true; } 33 | } 34 | 35 | public override Type UnderlyingType 36 | { 37 | get { return _fieldInfo.FieldType; } 38 | } 39 | 40 | public override bool IsReadOnly 41 | { 42 | get { return _fieldInfo.IsInitOnly; } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ClassMemberIndependent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using UpdateControls.Fields; 8 | 9 | namespace UpdateControls.XAML.Wrapper 10 | { 11 | public class ClassMemberIndependent : ClassMember 12 | { 13 | ClassMember _independent; 14 | PropertyInfo _valueProperty; 15 | 16 | public ClassMemberIndependent(ClassMember independent) 17 | : base(independent.Name, UnwrapType(independent.UnderlyingType), independent.ComponentType) 18 | { 19 | _independent = independent; 20 | _valueProperty = independent.UnderlyingType.GetProperty("Value"); 21 | } 22 | 23 | public override object GetObjectValue(object wrappedObject) 24 | { 25 | return _valueProperty.GetValue(_independent.GetObjectValue(wrappedObject)); 26 | } 27 | 28 | public override void SetObjectValue(object wrappedObject, object value) 29 | { 30 | _valueProperty.SetValue(_independent.GetObjectValue(wrappedObject), value); 31 | } 32 | 33 | public override bool CanRead 34 | { 35 | get { return true; } 36 | } 37 | 38 | public override Type UnderlyingType 39 | { 40 | get { return UnwrapType(_independent.UnderlyingType); } 41 | } 42 | 43 | public override bool IsReadOnly 44 | { 45 | get { return false; } 46 | } 47 | 48 | public static ClassMember Intercept(ClassMember member) 49 | { 50 | if (IsIndependent(member.UnderlyingType)) 51 | return new ClassMemberIndependent(member); 52 | else 53 | return member; 54 | } 55 | 56 | public static Type UnwrapType(Type independentType) 57 | { 58 | for (Type ancestor = independentType; ancestor != typeof(object) && ancestor != null; ancestor = ancestor.BaseType) 59 | if (ancestor.IsGenericType && ancestor.GetGenericTypeDefinition() == typeof(Independent<>)) 60 | return ancestor.GenericTypeArguments[0]; 61 | return null; 62 | } 63 | 64 | public static bool IsIndependent(Type memberType) 65 | { 66 | return UnwrapType(memberType) != null; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ClassMemberProperty.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections; 14 | using System.Collections.Specialized; 15 | using System.ComponentModel; 16 | using System.Linq; 17 | using System.Reflection; 18 | using System.Windows; 19 | using System.Windows.Input; 20 | using System.Windows.Threading; 21 | using System.Windows.Media; 22 | using System.Windows.Media.Effects; 23 | using System.Windows.Markup; 24 | 25 | namespace UpdateControls.XAML.Wrapper 26 | { 27 | public class ClassMemberProperty : ClassMember 28 | { 29 | private PropertyInfo _propertyInfo; 30 | 31 | public ClassMemberProperty(PropertyInfo property, Type objectInstanceType) 32 | : base(property.Name, property.PropertyType, objectInstanceType) 33 | { 34 | _propertyInfo = property; 35 | } 36 | 37 | public override object GetObjectValue(object wrappedObject) 38 | { 39 | // Get the property from the wrapped object. 40 | return _propertyInfo.GetValue(wrappedObject, null); 41 | } 42 | 43 | public override void SetObjectValue(object wrappedObject, object value) 44 | { 45 | if (_propertyInfo.CanWrite) 46 | _propertyInfo.SetValue(wrappedObject, value, null); 47 | } 48 | 49 | public override bool CanRead 50 | { 51 | get { return _propertyInfo.CanRead; } 52 | } 53 | 54 | public override Type UnderlyingType 55 | { 56 | get { return _propertyInfo.PropertyType; } 57 | } 58 | 59 | public override bool IsReadOnly 60 | { 61 | get { return !_propertyInfo.CanWrite; } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/CollectionItem.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.ObjectModel; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | class CollectionItem : IDisposable 18 | { 19 | private ObservableCollection _collection; 20 | private object _item; 21 | private bool _inCollection; 22 | 23 | public CollectionItem(ObservableCollection collection, object item, bool inCollection) 24 | { 25 | _collection = collection; 26 | _item = item; 27 | _inCollection = inCollection; 28 | } 29 | 30 | public void Dispose() 31 | { 32 | if (_inCollection) 33 | _collection.Remove(_item); 34 | } 35 | 36 | public void EnsureInCollection(int index) 37 | { 38 | if (!_inCollection) 39 | { 40 | // Insert the item into the correct position. 41 | _collection.Insert(index, _item); 42 | } 43 | else if (!object.Equals(_collection[index], _item)) 44 | { 45 | // Remove the item from the old position. 46 | _collection.Remove(_item); 47 | 48 | // Insert the item in the correct position. 49 | _collection.Insert(index, _item); 50 | } 51 | } 52 | 53 | public override int GetHashCode() 54 | { 55 | return _item.GetHashCode(); 56 | } 57 | 58 | public override bool Equals(object obj) 59 | { 60 | if (obj == null) 61 | return false; 62 | if (obj == this) 63 | return true; 64 | if (!(obj is CollectionItem)) 65 | return false; 66 | CollectionItem that = (CollectionItem)obj; 67 | return Object.Equals( 68 | this._item, 69 | that._item); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/IObjectInstance.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Windows.Threading; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | public interface IObjectInstance 18 | { 19 | ClassInstance ClassInstance { get; } 20 | object WrappedObject { get; } 21 | Dispatcher Dispatcher { get; } 22 | ObjectProperty LookupProperty(ClassMember classProperty); 23 | void FirePropertyChanged(string name); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ObjectProperty.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.ComponentModel; 14 | using System.Windows.Threading; 15 | 16 | namespace UpdateControls.XAML.Wrapper 17 | { 18 | public abstract class ObjectProperty 19 | { 20 | public IObjectInstance ObjectInstance { get; private set; } 21 | public ClassMember ClassProperty { get; private set; } 22 | 23 | public event EventHandler PropertyChanged; 24 | 25 | public ObjectProperty(IObjectInstance objectInstance, ClassMember classProperty) 26 | { 27 | ObjectInstance = objectInstance; 28 | ClassProperty = classProperty; 29 | } 30 | 31 | public void OnUserInput(object value) { BindingInterceptor.Current.SetValue(this, value); } 32 | public object Value { get { return BindingInterceptor.Current.GetValue(this); } } 33 | 34 | internal object ContinueGetValue() { return GetValue(); } 35 | internal void ContinueSetValue(object value) { SetValue(value); } 36 | internal void ContinueUpdateValue() { UpdateValue(); } 37 | 38 | protected abstract object GetValue(); 39 | protected abstract void SetValue(object value); 40 | protected abstract void UpdateValue(); 41 | 42 | public static ObjectProperty From(IObjectInstance objectInstance, ClassMember classProperty) 43 | { 44 | return classProperty.MakeObjectProperty(objectInstance); 45 | } 46 | 47 | public override string ToString() 48 | { 49 | return String.Format("{0}({1})", ClassProperty, ObjectInstance.WrappedObject); 50 | } 51 | 52 | protected object WrapObject(object value) 53 | { 54 | return typeof(ObjectInstance<>) 55 | .MakeGenericType(value.GetType()) 56 | .GetConstructor(new Type[] { typeof(object), typeof(Dispatcher) }) 57 | .Invoke(new object[] { value, ObjectInstance.Dispatcher }); 58 | } 59 | 60 | protected void FirePropertyChanged() 61 | { 62 | ObjectInstance.FirePropertyChanged(ClassProperty.Name); 63 | if (PropertyChanged != null) 64 | PropertyChanged(this, EventArgs.Empty); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ObjectPropertyAtomNative.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | 14 | namespace UpdateControls.XAML.Wrapper 15 | { 16 | class ObjectPropertyAtomNative : ObjectPropertyAtom 17 | { 18 | 19 | public ObjectPropertyAtomNative(IObjectInstance objectInstance, ClassMember classProperty) 20 | : base(objectInstance, classProperty) 21 | { 22 | } 23 | public override object TranslateIncommingValue(object value) 24 | { 25 | return value; 26 | } 27 | 28 | public override object TranslateOutgoingValue(object value) 29 | { 30 | return value; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ObjectPropertyAtomObject.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | class ObjectPropertyAtomObject : ObjectPropertyAtom 18 | { 19 | public ObjectPropertyAtomObject(IObjectInstance objectInstance, ClassMember classProperty) 20 | : base(objectInstance, classProperty) 21 | { 22 | } 23 | 24 | public override object TranslateIncommingValue(object value) 25 | { 26 | var instance = value as IObjectInstance; 27 | return instance != null ? instance.WrappedObject : value; 28 | } 29 | 30 | public override object TranslateOutgoingValue(object value) 31 | { 32 | if (value == null) 33 | return null; 34 | if (ClassProperty.UnderlyingType == typeof(object) && (ClassMember.IsPrimitive(value.GetType()) || typeof(IEnumerable).IsAssignableFrom(value.GetType()))) 35 | return value; 36 | return WrapObject(value); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ObjectPropertyCollectionNative.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | internal class ObjectPropertyCollectionNative : ObjectPropertyCollection 18 | { 19 | public ObjectPropertyCollectionNative(IObjectInstance objectInstance, ClassMember classProperty) 20 | : base(objectInstance, classProperty) 21 | { 22 | } 23 | 24 | public override object TranslateOutgoingValue(object value) 25 | { 26 | return value; 27 | } 28 | public override object TranslateIncomingValue(object value) 29 | { 30 | return value; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ObjectPropertyCollectionObject.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Collections; 15 | using System.Linq; 16 | 17 | namespace UpdateControls.XAML.Wrapper 18 | { 19 | internal class ObjectPropertyCollectionObject : ObjectPropertyCollection 20 | { 21 | public ObjectPropertyCollectionObject(IObjectInstance objectInstance, ClassMember classProperty) 22 | : base(objectInstance, classProperty) 23 | { 24 | } 25 | 26 | public override object TranslateOutgoingValue(object value) 27 | { 28 | return value == null ? null : WrapObject(value); 29 | } 30 | public override object TranslateIncomingValue(object value) 31 | { 32 | return ((IObjectInstance)value).WrappedObject; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /WPF/UpdateControls.XAML/Wrapper/ObjectPropertyCommand.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.Input; 7 | 8 | namespace UpdateControls.XAML.Wrapper 9 | { 10 | public class ObjectPropertyCommand : ObjectProperty, ICommand 11 | { 12 | ObjectProperty _canProperty; 13 | 14 | public ClassMemberCommand ClassCommand { get; private set; } 15 | 16 | public ObjectProperty CanExecuteProperty 17 | { 18 | get 19 | { 20 | if (_canProperty == null && ClassCommand.CanExecuteProperty != null) 21 | { 22 | _canProperty = ObjectInstance.LookupProperty(ClassCommand.CanExecuteProperty); 23 | _canProperty.PropertyChanged += (sender, args) => 24 | { 25 | if (CanExecuteChanged != null) 26 | CanExecuteChanged(this, EventArgs.Empty); 27 | }; 28 | } 29 | return _canProperty; 30 | } 31 | } 32 | 33 | public event EventHandler CanExecuteChanged; 34 | 35 | public ObjectPropertyCommand(IObjectInstance objectInstance, ClassMemberCommand classCommand) 36 | : base(objectInstance, classCommand) 37 | { 38 | ClassCommand = classCommand; 39 | } 40 | 41 | public bool CanExecute(object parameter) 42 | { 43 | if (CanExecuteProperty != null) 44 | return (bool)CanExecuteProperty.Value; 45 | else 46 | return true; 47 | } 48 | 49 | public void Execute(object parameter) 50 | { 51 | BindingInterceptor.Current.Execute(this); 52 | } 53 | 54 | internal void ContinueExecute() 55 | { 56 | ClassCommand.ExecuteMethod.Invoke(ObjectInstance.WrappedObject, new object[0]); 57 | } 58 | 59 | protected override object GetValue() { return this; } 60 | protected override void SetValue(object value) { } 61 | protected override void UpdateValue() { } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/IEnabledControl.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Text; 15 | 16 | namespace UpdateControls.Forms 17 | { 18 | public interface IEnabledControl 19 | { 20 | bool Enabled { get; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/IErrorControl.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Text; 15 | 16 | namespace UpdateControls.Forms 17 | { 18 | public interface IErrorControl 19 | { 20 | string GetError(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("UpdateControls.Forms")] 6 | [assembly: AssemblyProduct("UpdateControls.Forms")] 7 | [assembly: ComVisible(false)] 8 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateButton.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateCheckBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateCheckBox.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateCheckedListBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateCheckedListBox.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateComboBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateComboBox.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateComponent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateComponent.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateDateTimePicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateDateTimePicker.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateErrorProvider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateErrorProvider.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateFormMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateFormMap.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateGrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateGrid.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateLabel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateLabel.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateListBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateListBox.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateListView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateListView.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateMonthCalendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateMonthCalendar.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateRadioButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateRadioButton.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateTextBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateTextBox.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateTreeView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/ToolboxImages/UpdateTreeView.png -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateButton.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateCheckBox.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateCheckedListBox.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateComboBox.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateComponent.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateDateTimePicker.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateErrorProvider.Designer.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | using System; 3 | namespace UpdateControls.Forms 4 | { 5 | partial class UpdateErrorProvider 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private System.ComponentModel.IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && _visErrorText != null) 19 | { 20 | // Unregister idle-time updates. 21 | Application.Idle -= new EventHandler(Application_Idle); 22 | _visErrorText.Dispose(); 23 | foreach (ControlValidater dep in _controlSentry.Values) 24 | dep.Dispose(); 25 | } 26 | if (disposing && (components != null)) 27 | { 28 | components.Dispose(); 29 | } 30 | base.Dispose(disposing); 31 | } 32 | 33 | #region Component Designer generated code 34 | 35 | /// 36 | /// Required method for Designer support - do not modify 37 | /// the contents of this method with the code editor. 38 | /// 39 | private void InitializeComponent() 40 | { 41 | this.components = new System.ComponentModel.Container(); 42 | this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components); 43 | ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit(); 44 | ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit(); 45 | 46 | } 47 | 48 | #endregion 49 | 50 | private System.Windows.Forms.ErrorProvider errorProvider; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateFormMap.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateGrid.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsForms/UpdateControls.Forms/UpdateGrid.cs -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateGrid.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateLabel.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateListBox.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateListView.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateMonthCalendar.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateRadioButton.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateTextBox.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.3 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/UpdateTreeView.resx: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls.Forms/Util/UpdateController.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Text; 15 | 16 | namespace UpdateControls.Forms.Util 17 | { 18 | /// 19 | /// Protects update methods against reentrancy. 20 | /// 21 | /// Some APIs do not distinguish between user changes and programmatic 22 | /// changes. A user change should cause a property to be set, but a 23 | /// programmatic change should not. 24 | /// 25 | /// Create an UpdateController to manage the corresponding dependent 26 | /// property. Enclose the update method within using (). 27 | /// Then in the change event, use if () to 28 | /// ensure that reentrancy has not occurred. 29 | /// 30 | /// 31 | public class UpdateController 32 | { 33 | private class DisposeHelper : IDisposable 34 | { 35 | private UpdateController _updateController; 36 | 37 | public DisposeHelper(UpdateController updateContoller) 38 | { 39 | _updateController = updateContoller; 40 | } 41 | 42 | public void Dispose() 43 | { 44 | --_updateController._updating; 45 | } 46 | } 47 | 48 | private int _updating = 0; 49 | 50 | public bool NotUpdating { get { return _updating == 0; } } 51 | public IDisposable BeginUpdating() 52 | { 53 | ++_updating; 54 | return new DisposeHelper(this); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/Collections/DependentList.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2011 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | namespace UpdateControls.Collections 16 | { 17 | public class DependentList : IEnumerable 18 | { 19 | private readonly Func> _computeCollection; 20 | 21 | private List _list = new List(); 22 | private Dependent _dependentSentry; 23 | 24 | public DependentList(Func> computeCollection) 25 | { 26 | _computeCollection = computeCollection; 27 | 28 | _dependentSentry = new NamedDependent(MemoizedTypeName>.GenericName(), 29 | delegate { 30 | using (var bin = new RecycleBin(_list)) 31 | { 32 | _list.Clear(); 33 | 34 | foreach (T item in computeCollection()) 35 | _list.Add(bin.Extract(item)); 36 | } 37 | }); 38 | } 39 | 40 | public int IndexOf(T item) 41 | { 42 | _dependentSentry.OnGet(); 43 | return _list.IndexOf(item); 44 | } 45 | 46 | public T this[int index] 47 | { 48 | get 49 | { 50 | _dependentSentry.OnGet(); 51 | return _list[index]; 52 | } 53 | } 54 | 55 | public bool Contains(T item) 56 | { 57 | _dependentSentry.OnGet(); 58 | return _list.Contains(item); 59 | } 60 | 61 | public void CopyTo(T[] array, int arrayIndex) 62 | { 63 | _dependentSentry.OnGet(); 64 | _list.CopyTo(array, arrayIndex); 65 | } 66 | 67 | public int Count 68 | { 69 | get { _dependentSentry.OnGet(); return _list.Count; } 70 | } 71 | 72 | public IEnumerator GetEnumerator() 73 | { 74 | _dependentSentry.OnGet(); 75 | return _list.GetEnumerator(); 76 | } 77 | 78 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 79 | { 80 | _dependentSentry.OnGet(); 81 | return ((System.Collections.IEnumerable)_list).GetEnumerator(); 82 | } 83 | 84 | public Dependent DependentSentry 85 | { 86 | get { return _dependentSentry; } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/Collections/Impl/UpdateCollectionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls.Collections.Impl 7 | { 8 | /// Helper structure used by DependentDictionary and 9 | /// IndependentDictionary to represent the "Keys" and "Values" members. 10 | /// 11 | /// If you save a reference to the Keys or Values property of , 12 | /// the independent sentry should be informed when that collection is accessed. 13 | /// This helper class ensures that the sentry is notified. 14 | /// 15 | /// For , this class is even more 16 | /// important. Whenever DependentDictionary is updated, a new dictionary is 17 | /// created to hold the updated content, so the Keys and Values collections 18 | /// change frequently. This wrapper ensure that you do not accidentally hold 19 | /// a reference to an out-of-date version of the Keys or Values collection. 20 | /// It also ensures that the dictionary is updated if necessary when it is 21 | /// accessed through the Keys or Values collection. 22 | /// 23 | public struct UpdateCollectionHelper : ICollection 24 | { 25 | readonly Func> _get; 26 | 27 | public UpdateCollectionHelper(Func> getCollection) 28 | { 29 | _get = getCollection; 30 | } 31 | 32 | public void Add(T item) 33 | { 34 | throw new NotSupportedException(); 35 | } 36 | public void Clear() 37 | { 38 | throw new NotSupportedException(); 39 | } 40 | public bool Contains(T item) 41 | { 42 | return _get().Contains(item); 43 | } 44 | public void CopyTo(T[] array, int arrayIndex) 45 | { 46 | _get().CopyTo(array, arrayIndex); 47 | } 48 | public int Count 49 | { 50 | get { return _get().Count; } 51 | } 52 | public bool IsReadOnly 53 | { 54 | get { return true; } 55 | } 56 | public bool Remove(T item) 57 | { 58 | throw new NotSupportedException(); 59 | } 60 | 61 | public IEnumerator GetEnumerator() 62 | { 63 | return _get().GetEnumerator(); 64 | } 65 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 66 | { 67 | return GetEnumerator(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/Dependent.CurrentUpdate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace UpdateControls 5 | { 6 | public partial class Dependent 7 | { 8 | static partial void ReportCycles() 9 | { 10 | Trace.WriteLine(string.Format("Cycle discovered during update: {0}", Environment.StackTrace)); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/Fields/Dependent.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2011 Michael L Perry 5 | * MIT License 6 | * 7 | * This class based on a contribution by David Piepgrass. 8 | * 9 | * http://updatecontrols.net 10 | * http://www.codeplex.com/updatecontrols/ 11 | * 12 | **********************************************************************/ 13 | 14 | using System; 15 | using System.ComponentModel; 16 | 17 | namespace UpdateControls.Fields 18 | { 19 | public class Dependent : NamedDependent 20 | { 21 | protected internal T _value; 22 | protected Func _computeValue; 23 | 24 | public Dependent(Func compute) : base((string)null, null) 25 | { 26 | base._update = Update; _computeValue = compute; 27 | } 28 | public Dependent(string name, Func compute) : base(name, null) 29 | { 30 | base._update = Update; _computeValue = compute; 31 | } 32 | 33 | protected void Update() 34 | { 35 | _value = _computeValue(); 36 | // TODO: don't propagate updates when _value did not change. 37 | // T oldValue = _value; 38 | // _value = _computeValue(); 39 | // return _value == null ? oldValue != null : !_value.Equals(oldValue); 40 | } 41 | 42 | public T Value 43 | { 44 | get { base.OnGet(); return _value; } 45 | } 46 | public static implicit operator T(Dependent dependent) 47 | { 48 | return dependent.Value; 49 | } 50 | 51 | public override string VisualizerName(bool withValue) 52 | { 53 | string s = VisualizerName(_name ?? "NamedDependent"); 54 | if (withValue) 55 | s += " = " + (_value == null ? "null" : _value.ToString()); 56 | return s; 57 | } 58 | internal static string VisualizerName(string name) 59 | { 60 | string typeName = MemoizedTypeName.GenericName(); 61 | if (!string.IsNullOrEmpty(name)) 62 | return string.Format("{0}: {1}", name, typeName); 63 | else 64 | return typeName; 65 | } 66 | 67 | [Obsolete, EditorBrowsable(EditorBrowsableState.Never)] 68 | public Dependent DependentSentry 69 | { 70 | get { return this; } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/Fields/Independent.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2011 Michael L Perry 5 | * MIT License 6 | * 7 | * This class based on a contribution by David Piepgrass. 8 | * 9 | * http://updatecontrols.net 10 | * http://www.codeplex.com/updatecontrols/ 11 | * 12 | **********************************************************************/ 13 | using System; 14 | using System.ComponentModel; 15 | 16 | namespace UpdateControls.Fields 17 | { 18 | public class Independent : NamedIndependent 19 | { 20 | protected internal T _value; 21 | 22 | public Independent() { } 23 | public Independent(T value) : this((string)null, value) { } 24 | 25 | // Oops, this constructor causes ambiguity in case of Independent. 26 | // In that case, C# compilers will reinterpret existing code that previously 27 | // used the Independent(value) constructor to call Independent(name) instead. 28 | //public Independent(string name) : base(name) { } 29 | 30 | public Independent(string name, T value) : base(name) { _value = value; } 31 | public Independent(Type containerType, string name) : base(containerType, name) { } 32 | public Independent(Type containerType, string name, T value) : base(containerType, name) { _value = value; } 33 | 34 | public T Value 35 | { 36 | get { base.OnGet(); return _value; } 37 | set { 38 | if (_value == null ? value != null : !_value.Equals(value)) 39 | { 40 | base.OnSet(); 41 | _value = value; 42 | } 43 | } 44 | } 45 | public static implicit operator T(Independent independent) 46 | { 47 | return independent.Value; 48 | } 49 | 50 | public override string VisualizerName(bool withValue) 51 | { 52 | string s = "[I] " + Dependent.VisualizerName(Name); 53 | if (withValue) 54 | s += " = " + (_value == null ? "null" : _value.ToString()); 55 | return s; 56 | } 57 | 58 | [Obsolete, EditorBrowsable(EditorBrowsableState.Never)] 59 | public Independent IndependentSentry 60 | { 61 | get { return this; } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/IUpdatable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls 7 | { 8 | public interface IUpdatable 9 | { 10 | void UpdateNow(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/MemoizedTypeName.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace UpdateControls 7 | { 8 | /// .NET Framework reflection doesn't offer complete type names for 9 | /// generic types such as "List<int>" (the Type.Name value of that class is 10 | /// "List`1"). fills in the gap, and also saves the 11 | /// computed name for fast repeated lookups. 12 | public static class MemoizedTypeName 13 | { 14 | static Dictionary _shortNames = new Dictionary(); 15 | 16 | /// Computes a short language-agnostic name for a type, including 17 | /// generic parameters, e.g. GenericName(typeof(int)) is "Int32"; 18 | /// GenericName(typeof(Dictionary<int, string>)) is 19 | /// "Dictionary<Int32, String>". 20 | /// Type whose name you want 21 | /// Name with generic parameters, as explained in the summary. 22 | /// The result is memoized for generic types, so that the name is 23 | /// computed only once. 24 | public static string GenericName(Type type) 25 | { 26 | if (type == null) 27 | return null; 28 | string name; 29 | lock (_shortNames) 30 | { 31 | if (!_shortNames.TryGetValue(type, out name)) 32 | { 33 | if (type.IsGenericType) 34 | _shortNames[type] = name = ComputeGenericName(type); 35 | else 36 | name = type.Name; 37 | } 38 | } 39 | return name; 40 | } 41 | 42 | /// Computes a type's name without memoization. 43 | internal static string ComputeGenericName(Type type) 44 | { 45 | string result = type.Name; 46 | if (type.IsGenericType) 47 | { 48 | // remove genric indication (e.g. `1) 49 | result = result.Substring(0, result.LastIndexOf('`')); 50 | 51 | result = string.Format( 52 | "{0}<{1}>", 53 | result, 54 | string.Join(", ", type.GetGenericArguments() 55 | .Select(t => GenericName(t)).ToArray())); 56 | } 57 | return result; 58 | } 59 | 60 | /// Extension method on Type that is an alias for the method. 61 | public static string NameWithGenericParams(this Type t) 62 | { 63 | return GenericName(t); 64 | } 65 | } 66 | 67 | public static class MemoizedTypeName 68 | { 69 | static string _name; 70 | public static string GenericName() 71 | { 72 | if (_name == null) 73 | _name = MemoizedTypeName.GenericName(typeof(T)); 74 | return _name; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("UpdateControls")] 6 | [assembly: AssemblyProduct("UpdateControls")] 7 | [assembly: ComVisible(false)] 8 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/ThreadLocal.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | 4 | namespace UpdateControls 5 | { 6 | public class ThreadLocal 7 | { 8 | private Dictionary _valueByThread = new Dictionary(); 9 | 10 | public T Get() 11 | { 12 | lock (this) 13 | { 14 | T value; 15 | if (!_valueByThread.TryGetValue(Thread.CurrentThread.ManagedThreadId, out value)) 16 | return default(T); 17 | return value; 18 | } 19 | } 20 | 21 | public void Set(T value) 22 | { 23 | lock (this) 24 | { 25 | _valueByThread[Thread.CurrentThread.ManagedThreadId] = value; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/UpdateControlsExtensions.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://www.codeplex.com/updatecontrols/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | namespace UpdateControls 16 | { 17 | public static class UpdateControlsExtensions 18 | { 19 | /// 20 | /// Moves all objects into a new recycle bin, from which they can be extracted. 21 | /// 22 | /// A collection of objects to add to the bin. 23 | /// 24 | /// After the objects are added to the bin, the collection 25 | /// is cleared. Then it can be repopulated by extraction from 26 | /// the bin. 27 | /// 28 | public static RecycleBin Recycle(this ICollection collection) 29 | { 30 | RecycleBin bin = new RecycleBin(collection); 31 | 32 | if (collection != null) 33 | collection.Clear(); 34 | 35 | return bin; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WindowsForms/UpdateControls/UpdateScheduler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace UpdateControls 5 | { 6 | public class UpdateScheduler 7 | { 8 | private static Action _runOnUIThread; 9 | private static ThreadLocal _currentSet = new ThreadLocal(); 10 | 11 | public static void Initialize(Action runOnUIThread) 12 | { 13 | if (_runOnUIThread == null) 14 | { 15 | _runOnUIThread = runOnUIThread; 16 | } 17 | } 18 | 19 | public static UpdateScheduler Begin() 20 | { 21 | // If someone is already capturing the affected set, 22 | // let them keep that responsibility. 23 | if (_currentSet.Get() != null) 24 | return null; 25 | 26 | UpdateScheduler currentSet = new UpdateScheduler(); 27 | _currentSet.Set(currentSet); 28 | return currentSet; 29 | } 30 | 31 | public static void ScheduleUpdate(IUpdatable updatable) 32 | { 33 | UpdateScheduler currentSet = _currentSet.Get(); 34 | if (currentSet != null) 35 | currentSet._updatables.Add(updatable); 36 | else if (_runOnUIThread != null) 37 | _runOnUIThread(updatable.UpdateNow); 38 | else 39 | throw new InvalidOperationException( 40 | "Please call ForView.Initialize() on the UI thread."); 41 | } 42 | 43 | private List _updatables = new List(); 44 | 45 | public IEnumerable End() 46 | { 47 | System.Diagnostics.Debug.Assert(_currentSet.Get() == this); 48 | _currentSet.Set(null); 49 | return _updatables; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /WindowsPhone/UpdateControls.XAML/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using System.Resources; 5 | 6 | [assembly: AssemblyTitle("UpdateControls.XAML")] 7 | [assembly: AssemblyProduct("UpdateControls.XAML")] 8 | [assembly: ComVisible(false)] 9 | -------------------------------------------------------------------------------- /WindowsPhone/UpdateControls.XAML/Wrapper/ClassInstance.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrolslight.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Linq; 15 | using System.Reflection; 16 | 17 | namespace UpdateControls.XAML.Wrapper 18 | { 19 | class ClassInstance 20 | { 21 | private Type _wrappedType; 22 | private List _classProperties; 23 | 24 | public ClassInstance(Type wrappedType) 25 | { 26 | _wrappedType = wrappedType; 27 | 28 | // Create a wrapper for each non-collection property. 29 | _classProperties = _wrappedType 30 | .GetProperties(BindingFlags.Public | BindingFlags.Instance) 31 | .Select(p => new ClassProperty(p, _wrappedType)) 32 | .ToList(); 33 | } 34 | 35 | public IEnumerable ClassProperties 36 | { 37 | get { return _classProperties; } 38 | } 39 | 40 | public override string ToString() 41 | { 42 | return _wrappedType.Name; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /WindowsPhone/UpdateControls.XAML/Wrapper/CollectionItem.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Collections.ObjectModel; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | class CollectionItem : IDisposable 18 | { 19 | private ObservableCollection _collection; 20 | private object _item; 21 | private bool _inCollection; 22 | 23 | public CollectionItem(ObservableCollection collection, object item, bool inCollection) 24 | { 25 | _collection = collection; 26 | _item = item; 27 | _inCollection = inCollection; 28 | } 29 | 30 | public void Dispose() 31 | { 32 | if (_inCollection) 33 | _collection.Remove(_item); 34 | } 35 | 36 | public void EnsureInCollection(int index) 37 | { 38 | if (!_inCollection) 39 | { 40 | // Insert the item into the correct position. 41 | _collection.Insert(index, _item); 42 | } 43 | else if (!object.Equals(_collection[index], _item)) 44 | { 45 | // Remove the item from the old position. 46 | _collection.Remove(_item); 47 | 48 | // Insert the item in the correct position. 49 | _collection.Insert(index, _item); 50 | } 51 | } 52 | 53 | public override int GetHashCode() 54 | { 55 | return _item.GetHashCode(); 56 | } 57 | 58 | public override bool Equals(object obj) 59 | { 60 | if (obj == null) 61 | return false; 62 | if (obj == this) 63 | return true; 64 | if (!(obj is CollectionItem)) 65 | return false; 66 | CollectionItem that = (CollectionItem)obj; 67 | return Object.Equals( 68 | this._item, 69 | that._item); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /WindowsPhone/UpdateControls.XAML/Wrapper/IObjectInstance.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrolslight.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Windows; 14 | using System.Windows.Threading; 15 | 16 | namespace UpdateControls.XAML.Wrapper 17 | { 18 | public interface IObjectInstance : IDisposable 19 | { 20 | object WrappedObject { get; } 21 | Tree Tree { get; } 22 | void Defer(Dependent dependent); 23 | ObjectProperty LookupProperty(UpdateControls.XAML.Wrapper.ClassProperty classProperty); 24 | void SetValue(DependencyProperty dependencyProperty, object value); 25 | void ClearValue(DependencyProperty dependencyProperty); 26 | void UpdateNodes(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /WindowsPhone/UpdateControls.XAML/Wrapper/NotificationGate.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrols.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | 14 | namespace UpdateControls.XAML.Wrapper 15 | { 16 | class NotificationGate : IDisposable 17 | { 18 | private static ThreadLocal _outboundCount = new ThreadLocal(); 19 | 20 | private NotificationGate() 21 | { 22 | } 23 | 24 | public static bool IsInbound 25 | { 26 | get { return _outboundCount.Get() == 0; } 27 | } 28 | 29 | public static IDisposable BeginOutbound() 30 | { 31 | int outboundCount = _outboundCount.Get(); 32 | _outboundCount.Set(outboundCount + 1); 33 | return new NotificationGate(); 34 | } 35 | 36 | public void Dispose() 37 | { 38 | int outboundCount = _outboundCount.Get(); 39 | _outboundCount.Set(outboundCount - 1); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /WindowsPhone/UpdateControls.XAML/Wrapper/ObjectProperty.cs: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * 3 | * Update Controls .NET 4 | * Copyright 2010 Michael L Perry 5 | * MIT License 6 | * 7 | * http://updatecontrols.net 8 | * http://updatecontrolslight.codeplex.com/ 9 | * 10 | **********************************************************************/ 11 | 12 | using System; 13 | using System.Linq; 14 | 15 | namespace UpdateControls.XAML.Wrapper 16 | { 17 | public abstract class ObjectProperty : IDisposable 18 | { 19 | public IObjectInstance ObjectInstance { get; private set; } 20 | public ClassProperty ClassProperty { get; private set; } 21 | 22 | public ObjectProperty(IObjectInstance objectInstance, ClassProperty classProperty) 23 | { 24 | ObjectInstance = objectInstance; 25 | ClassProperty = classProperty; 26 | } 27 | 28 | public abstract void OnUserInput(object value); 29 | public abstract void UpdateNodes(); 30 | public abstract void Dispose(); 31 | 32 | public static ObjectProperty From(IObjectInstance objectInstance, ClassProperty classProperty) 33 | { 34 | return classProperty.MakeObjectProperty(objectInstance); 35 | } 36 | 37 | public override string ToString() 38 | { 39 | return String.Format("{0}({1})", ClassProperty, ObjectInstance.WrappedObject); 40 | } 41 | 42 | protected bool WrapObject(object value, out IObjectInstance wrapper) 43 | { 44 | return ObjectInstance.Tree.WrapObject(value, out wrapper); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /WindowsPhone/UpdateControls.XAML/Wrapper/Tree.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Net; 4 | using System.Windows; 5 | using System.Windows.Controls; 6 | using System.Windows.Documents; 7 | using System.Windows.Ink; 8 | using System.Windows.Input; 9 | using System.Windows.Media; 10 | using System.Windows.Media.Animation; 11 | using System.Windows.Shapes; 12 | using System.Collections.Generic; 13 | 14 | namespace UpdateControls.XAML.Wrapper 15 | { 16 | public class Tree : IUpdatable 17 | { 18 | private Dictionary _wrapperByObject = new Dictionary(); 19 | private IObjectInstance _root; 20 | private Dependent _depNodes; 21 | 22 | public Tree() 23 | { 24 | _depNodes = new Dependent(delegate 25 | { 26 | _root.UpdateNodes(); 27 | }); 28 | _depNodes.Invalidated += () => UpdateScheduler.ScheduleUpdate(this); 29 | } 30 | 31 | public void SetRoot(IObjectInstance root) 32 | { 33 | _root = root; 34 | _depNodes.Touch(); 35 | } 36 | 37 | public bool WrapObject(object value, out IObjectInstance wrapper) 38 | { 39 | if (!_wrapperByObject.TryGetValue(value, out wrapper)) 40 | { 41 | wrapper = (IObjectInstance)typeof(ObjectInstance<>) 42 | .MakeGenericType(value.GetType()) 43 | .GetConstructors() 44 | .Single() 45 | .Invoke(new object[] { value, this }); 46 | _wrapperByObject.Add(value, wrapper); 47 | return true; 48 | } 49 | else 50 | return false; 51 | } 52 | 53 | public void RemoveKey(object key) 54 | { 55 | _wrapperByObject.Remove(key); 56 | } 57 | 58 | public void UpdateNow() 59 | { 60 | _depNodes.OnGet(); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /WindowsPhone/UpdateControls.XAML/Wrapper/UnitTestDispatcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace UpdateControls.XAML.Wrapper 5 | { 6 | public static class UnitTestDispatcher 7 | { 8 | [ThreadStatic] 9 | private static List _deferredActions = new List(); 10 | 11 | [ThreadStatic] 12 | public static bool On = false; 13 | 14 | public static void Defer(Action action) 15 | { 16 | _deferredActions.Add(action); 17 | } 18 | 19 | public static bool ExecuteAll() 20 | { 21 | int loopCount = 3; 22 | while (_deferredActions.Count > 0 && loopCount > 0) 23 | { 24 | List actions = new List(_deferredActions); 25 | _deferredActions.Clear(); 26 | foreach (Action action in actions) 27 | action(); 28 | --loopCount; 29 | } 30 | return loopCount > 0; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/Assets/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsStore/UpdateControls.Test.App/Assets/Logo.png -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/Assets/SmallLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsStore/UpdateControls.Test.App/Assets/SmallLogo.png -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/Assets/SplashScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsStore/UpdateControls.Test.App/Assets/SplashScreen.png -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsStore/UpdateControls.Test.App/Assets/StoreLogo.png -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/DebugConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.UI.Xaml.Data; 7 | 8 | namespace UpdateControls.Test.App 9 | { 10 | public class DebugConverter : IValueConverter 11 | { 12 | public object Convert(object value, Type targetType, object parameter, string language) 13 | { 14 | return value; 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, string language) 18 | { 19 | return value; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using UpdateControls.Test; 6 | using Windows.Foundation; 7 | using Windows.Foundation.Collections; 8 | using Windows.UI.Xaml; 9 | using Windows.UI.Xaml.Controls; 10 | using Windows.UI.Xaml.Controls.Primitives; 11 | using Windows.UI.Xaml.Data; 12 | using Windows.UI.Xaml.Input; 13 | using Windows.UI.Xaml.Media; 14 | using Windows.UI.Xaml.Navigation; 15 | 16 | // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 17 | 18 | namespace UpdateControls.Test.App 19 | { 20 | /// 21 | /// An empty page that can be used on its own or navigated to within a Frame. 22 | /// 23 | public sealed partial class MainPage : Page 24 | { 25 | public MainPage() 26 | { 27 | this.InitializeComponent(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | UpdateControls.Test.App 6 | Michael 7 | Assets\StoreLogo.png 8 | 9 | 10 | 6.3.0 11 | 6.3.0 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/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("UpdateControls.Test.App")] 9 | [assembly: AssemblyProduct("UpdateControls.Test.App")] 10 | 11 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/UpdateControls.XAML.Test_TemporaryKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaellperry/UpdateControls/8b300b8faca6cc4712f3fd748701b0c0449ca8e4/WindowsStore/UpdateControls.Test.App/UpdateControls.XAML.Test_TemporaryKey.pfx -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/ViewModelLocator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using UpdateControls.XAML; 7 | using UpdateControls.Test; 8 | 9 | namespace UpdateControls.Test.App 10 | { 11 | public class ViewModelLocator : ViewModelLocatorBase 12 | { 13 | private ContactList _contactList; 14 | private ContactListNavigationModel _navigation; 15 | 16 | public ViewModelLocator() 17 | { 18 | _contactList = new ContactList(); 19 | _navigation = new ContactListNavigationModel(); 20 | 21 | Person mike = _contactList.NewPerson(); 22 | mike.Prefix = PrefixID.Mr; 23 | mike.First = "Michael"; 24 | mike.Last = "Perry"; 25 | mike.Gender = GenderEnum.Male; 26 | Person jenny = _contactList.NewPerson(); 27 | jenny.Prefix = PrefixID.Mrs; 28 | jenny.First = "Jennifer"; 29 | jenny.Last = "Perry"; 30 | jenny.Gender = GenderEnum.Female; 31 | Person.Marry(mike, jenny); 32 | } 33 | 34 | public object Main 35 | { 36 | get 37 | { 38 | return ViewModel(() => new ContactListViewModel( 39 | _contactList, 40 | _navigation)); 41 | } 42 | } 43 | 44 | public object PersonDetail 45 | { 46 | get 47 | { 48 | return ViewModel(() => _navigation.SelectedPerson == null 49 | ? null 50 | : new PersonViewModel( 51 | _navigation.SelectedPerson, 52 | _contactList)); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /WindowsStore/UpdateControls.Test.App/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | --------------------------------------------------------------------------------