├── .gitignore
├── .nuget
├── NuGet.Config
├── NuGet.targets
└── nuget.exe
├── License.txt
├── VirtualCollection.Web
├── Properties
│ └── AssemblyInfo.cs
├── Silverlight.js
├── VirtualCollection.Web.csproj
├── VirtualCollectionTestPage.aspx
├── VirtualCollectionTestPage.html
├── Web.Debug.config
├── Web.Release.config
└── Web.config
├── VirtualCollection.sln
└── VirtualCollection
├── App.xaml
├── App.xaml.cs
├── BusynessIndicator.xaml
├── BusynessIndicator.xaml.cs
├── Demo
├── MainViewModel.cs
├── NorthwindProductsSource.cs
├── Schedulers.cs
└── StringToImageConverter.cs
├── Framework
├── Behaviors
│ └── NotifyViewModelOfLifeCycleEvents.cs
├── Converters
│ ├── StringValueConversion.cs
│ ├── StringValueConversionCollection.cs
│ └── StringValueToObjectConverter.cs
├── Extensions
│ ├── INotifyPropertyChangedExtensions.cs
│ └── SymbolExtensions.cs
└── MVVM
│ ├── ActionCommand.cs
│ ├── CommandBase.cs
│ ├── CommandHolder.cs
│ ├── IViewModel.cs
│ └── ViewModel.cs
├── MainPage.xaml
├── MainPage.xaml.cs
├── Properties
├── AppManifest.xml
└── AssemblyInfo.cs
├── Service References
└── Northwind
│ ├── Reference.cs
│ ├── Reference.datasvcmap
│ └── service.edmx
├── VirtualCollection.csproj
├── VirtualCollection
├── DeferredActionInvoker.cs
├── Disposer.cs
├── IEnquireAboutItemVisibility.cs
├── INotifyBusyness.cs
├── IVirtualCollectionSource.cs
├── ItemsRealizedEventArgs.cs
├── MostRecentUsedList.cs
├── ProvideVisibleItemRangeFromDataGridBehavior.cs
├── ProvideVisibleItemRangeFromItemsControlBehavior.cs
├── RefreshMode.cs
├── SparseList.cs
├── VirtualCollection.cs
├── VirtualCollectionSource.cs
├── VirtualItem.cs
├── VirtualizingWrapPanel.cs
├── WeakCollectionViewWrapper.cs
└── WeakEventListener.cs
└── packages.config
/.gitignore:
--------------------------------------------------------------------------------
1 | _ReSharper*
2 | VirtualCollection/Bin/
3 | *.user
4 | VirtualCollection/obj/
5 | *.suo
6 | [Bb]in
7 | [Oo]bj
8 | ClientBin
9 | packages/
10 |
--------------------------------------------------------------------------------
/.nuget/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.nuget/NuGet.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildProjectDirectory)\..\
5 |
6 |
7 | false
8 |
9 |
10 | false
11 |
12 |
13 | false
14 |
15 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
27 | $([System.IO.Path]::Combine($(ProjectDir), "packages.config"))
28 | $([System.IO.Path]::Combine($(SolutionDir), "packages"))
29 |
30 |
31 |
32 |
33 | $(SolutionDir).nuget
34 | packages.config
35 | $(SolutionDir)packages
36 |
37 |
38 |
39 |
40 | $(NuGetToolsPath)\nuget.exe
41 | @(PackageSource)
42 |
43 | "$(NuGetExePath)"
44 | mono --runtime=v4.0.30319 $(NuGetExePath)
45 |
46 | $(TargetDir.Trim('\\'))
47 |
48 |
49 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" -o "$(PackagesDir)"
50 | $(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols
51 |
52 |
53 |
54 | RestorePackages;
55 | $(BuildDependsOn);
56 |
57 |
58 |
59 |
60 | $(BuildDependsOn);
61 | BuildPackage;
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
82 |
84 |
85 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/.nuget/nuget.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samueldjack/VirtualCollection/bbce670015b1a0af6332ea3ecfd20b28384573c9/.nuget/nuget.exe
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 | Boost Software License - Version 1.0 - August 17th, 2003
2 |
3 | Permission is hereby granted, free of charge, to any person or organization
4 | obtaining a copy of the software and accompanying documentation covered by
5 | this license (the "Software") to use, reproduce, display, distribute,
6 | execute, and transmit the Software, and to prepare derivative works of the
7 | Software, and to permit third-parties to whom the Software is furnished to
8 | do so, all subject to the following:
9 |
10 | The copyright notices in the Software and this entire statement, including
11 | the above license grant, this restriction and the following disclaimer,
12 | must be included in all copies of the Software, in whole or in part, and
13 | all derivative works of the Software, unless such copies or derivative
14 | works are solely in the form of machine-executable object code generated by
15 | a source language processor.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/VirtualCollection.Web/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("VirtualCollection.Web")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("VirtualCollection.Web")]
13 | [assembly: AssemblyCopyright("Copyright © 2012")]
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("730913a8-a15b-421f-af04-1f76837fcf13")]
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 Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/VirtualCollection.Web/Silverlight.js:
--------------------------------------------------------------------------------
1 | //v2.0.30511.0
2 | if(!window.Silverlight)window.Silverlight={};Silverlight._silverlightCount=0;Silverlight.__onSilverlightInstalledCalled=false;Silverlight.fwlinkRoot="http://go2.microsoft.com/fwlink/?LinkID=";Silverlight.__installationEventFired=false;Silverlight.onGetSilverlight=null;Silverlight.onSilverlightInstalled=function(){window.location.reload(false)};Silverlight.isInstalled=function(b){if(b==undefined)b=null;var a=false,m=null;try{var i=null,j=false;if(window.ActiveXObject)try{i=new ActiveXObject("AgControl.AgControl");if(b===null)a=true;else if(i.IsVersionSupported(b))a=true;i=null}catch(l){j=true}else j=true;if(j){var k=navigator.plugins["Silverlight Plug-In"];if(k)if(b===null)a=true;else{var h=k.description;if(h==="1.0.30226.2")h="2.0.30226.2";var c=h.split(".");while(c.length>3)c.pop();while(c.length<4)c.push(0);var e=b.split(".");while(e.length>4)e.pop();var d,g,f=0;do{d=parseInt(e[f]);g=parseInt(c[f]);f++}while(f");delete a.id;delete a.width;delete a.height;for(var c in a)if(a[c])b.push('');b.push("");return b.join("")};Silverlight.createObjectEx=function(b){var a=b,c=Silverlight.createObject(a.source,a.parentElement,a.id,a.properties,a.events,a.initParams,a.context);if(a.parentElement==null)return c};Silverlight.buildPromptHTML=function(b){var a="",d=Silverlight.fwlinkRoot,c=b.version;if(b.alt)a=b.alt;else{if(!c)c="";a="
";a=a.replace("{1}",c);a=a.replace("{2}",d+"108181")}return a};Silverlight.getSilverlight=function(e){if(Silverlight.onGetSilverlight)Silverlight.onGetSilverlight();var b="",a=String(e).split(".");if(a.length>1){var c=parseInt(a[0]);if(isNaN(c)||c<2)b="1.0";else b=a[0]+"."+a[1]}var d="";if(b.match(/^\d+\056\d+$/))d="&v="+b;Silverlight.followFWLink("149156"+d)};Silverlight.followFWLink=function(a){top.location=Silverlight.fwlinkRoot+String(a)};Silverlight.HtmlAttributeEncode=function(c){var a,b="";if(c==null)return null;for(var d=0;d96&&a<123||a>64&&a<91||a>43&&a<58&&a!=47||a==95)b=b+String.fromCharCode(a);else b=b+""+a+";"}return b};Silverlight.default_error_handler=function(e,b){var d,c=b.ErrorType;d=b.ErrorCode;var a="\nSilverlight error message \n";a+="ErrorCode: "+d+"\n";a+="ErrorType: "+c+" \n";a+="Message: "+b.ErrorMessage+" \n";if(c=="ParserError"){a+="XamlFile: "+b.xamlFile+" \n";a+="Line: "+b.lineNumber+" \n";a+="Position: "+b.charPosition+" \n"}else if(c=="RuntimeError"){if(b.lineNumber!=0){a+="Line: "+b.lineNumber+" \n";a+="Position: "+b.charPosition+" \n"}a+="MethodName: "+b.methodName+" \n"}alert(a)};Silverlight.__cleanup=function(){for(var a=Silverlight._silverlightCount-1;a>=0;a--)window["__slEvent"+a]=null;Silverlight._silverlightCount=0;if(window.removeEventListener)window.removeEventListener("unload",Silverlight.__cleanup,false);else window.detachEvent("onunload",Silverlight.__cleanup)};Silverlight.__getHandlerName=function(b){var a="";if(typeof b=="string")a=b;else if(typeof b=="function"){if(Silverlight._silverlightCount==0)if(window.addEventListener)window.addEventListener("onunload",Silverlight.__cleanup,false);else window.attachEvent("onunload",Silverlight.__cleanup);var c=Silverlight._silverlightCount++;a="__slEvent"+c;window[a]=b}else a=null;return a};Silverlight.onRequiredVersionAvailable=function(){};Silverlight.onRestartRequired=function(){};Silverlight.onUpgradeRequired=function(){};Silverlight.onInstallRequired=function(){};Silverlight.IsVersionAvailableOnError=function(d,a){var b=false;try{if(a.ErrorCode==8001&&!Silverlight.__installationEventFired){Silverlight.onUpgradeRequired();Silverlight.__installationEventFired=true}else if(a.ErrorCode==8002&&!Silverlight.__installationEventFired){Silverlight.onRestartRequired();Silverlight.__installationEventFired=true}else if(a.ErrorCode==5014||a.ErrorCode==2106){if(Silverlight.__verifySilverlight2UpgradeSuccess(a.getHost()))b=true}else b=true}catch(c){}return b};Silverlight.IsVersionAvailableOnLoad=function(b){var a=false;try{if(Silverlight.__verifySilverlight2UpgradeSuccess(b.getHost()))a=true}catch(c){}return a};Silverlight.__verifySilverlight2UpgradeSuccess=function(d){var c=false,b="2.0.31005",a=null;try{if(d.IsVersionSupported(b+".99")){a=Silverlight.onRequiredVersionAvailable;c=true}else if(d.IsVersionSupported(b+".0"))a=Silverlight.onRestartRequired;else a=Silverlight.onUpgradeRequired;if(a&&!Silverlight.__installationEventFired){a();Silverlight.__installationEventFired=true}}catch(e){}return c}
--------------------------------------------------------------------------------
/VirtualCollection.Web/VirtualCollection.Web.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 |
8 |
9 | 2.0
10 | {E8E63401-D8B0-42C5-8D15-9D68CE8641BB}
11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
12 | Library
13 | Properties
14 | VirtualCollection.Web
15 | VirtualCollection.Web
16 | v4.0
17 | false
18 | {19D96D76-77F4-456C-A04B-44F5FF9172E3}|..\VirtualCollection\VirtualCollection.csproj|ClientBin|False
19 |
20 |
21 |
22 |
23 | 4.0
24 |
25 |
26 | true
27 | full
28 | false
29 | bin\
30 | DEBUG;TRACE
31 | prompt
32 | 4
33 |
34 |
35 | pdbonly
36 | true
37 | bin\
38 | TRACE
39 | prompt
40 | 4
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | Web.config
68 |
69 |
70 | Web.config
71 |
72 |
73 |
74 |
75 |
76 |
77 | 10.0
78 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | False
88 | True
89 | 50505
90 | /
91 |
92 |
93 | False
94 | False
95 |
96 |
97 | False
98 |
99 |
100 |
101 |
102 |
109 |
--------------------------------------------------------------------------------
/VirtualCollection.Web/VirtualCollectionTestPage.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="c#" AutoEventWireup="true" %>
2 |
3 |
4 |
5 |
6 | VirtualCollection
7 |
21 |
22 |
58 |
59 |
60 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/VirtualCollection.Web/VirtualCollectionTestPage.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | VirtualCollection
6 |
20 |
21 |
57 |
58 |
59 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/VirtualCollection.Web/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
29 |
30 |
--------------------------------------------------------------------------------
/VirtualCollection.Web/Web.Release.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
19 |
30 |
31 |
--------------------------------------------------------------------------------
/VirtualCollection.Web/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/VirtualCollection.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{60BC5A25-0D86-4E1C-A9AD-39655475B12B}"
5 | ProjectSection(SolutionItems) = preProject
6 | .nuget\NuGet.Config = .nuget\NuGet.Config
7 | .nuget\nuget.exe = .nuget\nuget.exe
8 | .nuget\NuGet.targets = .nuget\NuGet.targets
9 | EndProjectSection
10 | EndProject
11 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualCollection", "VirtualCollection\VirtualCollection.csproj", "{19D96D76-77F4-456C-A04B-44F5FF9172E3}"
12 | EndProject
13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualCollection.Web", "VirtualCollection.Web\VirtualCollection.Web.csproj", "{E8E63401-D8B0-42C5-8D15-9D68CE8641BB}"
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {19D96D76-77F4-456C-A04B-44F5FF9172E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {19D96D76-77F4-456C-A04B-44F5FF9172E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {19D96D76-77F4-456C-A04B-44F5FF9172E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {19D96D76-77F4-456C-A04B-44F5FF9172E3}.Release|Any CPU.Build.0 = Release|Any CPU
25 | {E8E63401-D8B0-42C5-8D15-9D68CE8641BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {E8E63401-D8B0-42C5-8D15-9D68CE8641BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {E8E63401-D8B0-42C5-8D15-9D68CE8641BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {E8E63401-D8B0-42C5-8D15-9D68CE8641BB}.Release|Any CPU.Build.0 = Release|Any CPU
29 | EndGlobalSection
30 | GlobalSection(SolutionProperties) = preSolution
31 | HideSolutionNode = FALSE
32 | EndGlobalSection
33 | EndGlobal
34 |
--------------------------------------------------------------------------------
/VirtualCollection/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/VirtualCollection/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Documents;
9 | using System.Windows.Input;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Animation;
12 | using System.Windows.Shapes;
13 | using VirtualCollection.Demo;
14 |
15 | namespace VirtualCollection
16 | {
17 | public partial class App : Application
18 | {
19 |
20 | public App()
21 | {
22 | this.Startup += this.Application_Startup;
23 | this.Exit += this.Application_Exit;
24 | this.UnhandledException += this.Application_UnhandledException;
25 |
26 | InitializeComponent();
27 | }
28 |
29 | private void Application_Startup(object sender, StartupEventArgs e)
30 | {
31 | Schedulers.UIThread = TaskScheduler.FromCurrentSynchronizationContext();
32 |
33 | this.RootVisual = new MainPage();
34 | }
35 |
36 | private void Application_Exit(object sender, EventArgs e)
37 | {
38 |
39 | }
40 |
41 | private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
42 | {
43 | // If the app is running outside of the debugger then report the exception using
44 | // the browser's exception mechanism. On IE this will display it a yellow alert
45 | // icon in the status bar and Firefox will display a script error.
46 | if (!System.Diagnostics.Debugger.IsAttached)
47 | {
48 |
49 | // NOTE: This will allow the application to continue running after an exception has been thrown
50 | // but not handled.
51 | // For production applications this error handling should be replaced with something that will
52 | // report the error to the website and stop the application.
53 | e.Handled = true;
54 | Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
55 | }
56 | }
57 |
58 | private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
59 | {
60 | try
61 | {
62 | string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
63 | errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");
64 |
65 | System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
66 | }
67 | catch (Exception)
68 | {
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/VirtualCollection/BusynessIndicator.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/VirtualCollection/BusynessIndicator.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 | using VirtualCollection.VirtualCollection;
5 |
6 | namespace VirtualCollection
7 | {
8 | public partial class BusynessIndicator : UserControl
9 | {
10 | public static readonly DependencyProperty BusyBodyProperty =
11 | DependencyProperty.Register("BusyBody", typeof(INotifyBusyness), typeof(BusynessIndicator), new PropertyMetadata(default(INotifyBusyness), HandleSourceChanged));
12 |
13 | private static void HandleSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
14 | {
15 | var notifier = d as BusynessIndicator;
16 |
17 | if (e.OldValue != null)
18 | {
19 | (e.OldValue as INotifyBusyness).IsBusyChanged -= notifier.IsBusyChanged;
20 | }
21 |
22 | if (e.NewValue != null)
23 | {
24 | (e.NewValue as INotifyBusyness).IsBusyChanged += notifier.IsBusyChanged;
25 | }
26 | }
27 |
28 | private void IsBusyChanged(object sender, EventArgs e)
29 | {
30 | if (Dispatcher.CheckAccess())
31 | {
32 | UpdateState();
33 | }
34 | else
35 | {
36 | Dispatcher.BeginInvoke(UpdateState);
37 | }
38 | }
39 |
40 | private void UpdateState()
41 | {
42 | if (BusyBody != null && BusyBody.IsBusy)
43 | {
44 | VisualStateManager.GoToState(this, "Busy", true);
45 | }
46 | else
47 | {
48 | VisualStateManager.GoToState(this, "Idle", true);
49 | }
50 | }
51 |
52 | public INotifyBusyness BusyBody
53 | {
54 | get { return (INotifyBusyness)GetValue(BusyBodyProperty); }
55 | set { SetValue(BusyBodyProperty, value); }
56 | }
57 |
58 | public BusynessIndicator()
59 | {
60 | InitializeComponent();
61 |
62 | VisualStateManager.GoToState(this, "Idle", true);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/VirtualCollection/Demo/MainViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.Services.Client;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Documents;
10 | using System.Windows.Ink;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Animation;
14 | using System.Windows.Shapes;
15 | using VirtualCollection.Framework.MVVM;
16 | using VirtualCollection.Northwind;
17 | using VirtualCollection.VirtualCollection;
18 | using VirtualCollection.Framework.Extensions;
19 | using System.Reactive.Linq;
20 |
21 | namespace VirtualCollection.Demo
22 | {
23 | public class MainViewModel : ViewModel
24 | {
25 | private string _search;
26 | private NorthwindProductsSource _source;
27 | private string _displayStyle;
28 |
29 | public string Search
30 | {
31 | get { return _search; }
32 | set
33 | {
34 | _search = value;
35 | RaisePropertyChanged(() => Search);
36 | }
37 | }
38 |
39 | public string DisplayStyle
40 | {
41 | get { return _displayStyle; }
42 | set
43 | {
44 | _displayStyle = value;
45 | RaisePropertyChanged(() => DisplayStyle);
46 | }
47 | }
48 |
49 | public IList DisplayStyles { get { return new[] {"Card", "Details"}; } }
50 |
51 | public VirtualCollection Items { get; private set; }
52 |
53 | public MainViewModel()
54 | {
55 | _source = new NorthwindProductsSource();
56 | Items = new VirtualCollection(_source, pageSize: 20, cachedPages: 5);
57 |
58 | this.ObservePropertyChanged(() => Search)
59 | .Throttle(TimeSpan.FromSeconds(0.25))
60 | .ObserveOnDispatcher()
61 | .Subscribe(_ => _source.Search = Search);
62 |
63 | DisplayStyle = "Details";
64 | }
65 |
66 | protected override void OnViewLoaded()
67 | {
68 | Items.Refresh();
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/VirtualCollection/Demo/NorthwindProductsSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data.Services.Client;
5 | using System.Linq;
6 | using System.Net;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows;
10 | using System.Windows.Controls;
11 | using System.Windows.Documents;
12 | using System.Windows.Ink;
13 | using System.Windows.Input;
14 | using System.Windows.Media;
15 | using System.Windows.Media.Animation;
16 | using System.Windows.Shapes;
17 | using VirtualCollection.Northwind;
18 | using VirtualCollection.VirtualCollection;
19 |
20 | namespace VirtualCollection.Demo
21 | {
22 | public class NorthwindProductsSource : VirtualCollectionSource
23 | {
24 | private string _search;
25 |
26 | public string Search
27 | {
28 | get { return _search; }
29 | set
30 | {
31 | _search = value;
32 | Refresh(RefreshMode.ClearStaleData);
33 | }
34 | }
35 |
36 | protected override Task> GetPageAsyncOverride(int start, int pageSize, IList sortDescriptions)
37 | {
38 | return GetQueryResults(start, pageSize, sortDescriptions)
39 | .ContinueWith(t =>
40 | {
41 | SetCount((int)t.Result.TotalCount);
42 | return (IList)((IEnumerable)t.Result).ToList();
43 |
44 | }, TaskContinuationOptions.ExecuteSynchronously);
45 | }
46 |
47 | private Task> GetQueryResults(int start, int pageSize, IList sortDescriptions)
48 | {
49 | var context = new NorthwindEntities(new Uri("http://services.odata.org/Northwind/Northwind.svc/"));
50 |
51 | var orderByString = CreateOrderByString(sortDescriptions);
52 | var query = context.Products
53 | .AddQueryOption("$skip", start)
54 | .AddQueryOption("$top", pageSize)
55 | .IncludeTotalCount();
56 |
57 | if (!string.IsNullOrEmpty(Search))
58 | {
59 | query = query.AddQueryOption("$filter", "(substringof('" + Search + "',ProductName) eq true)");
60 | }
61 |
62 | if (orderByString.Length > 0)
63 | {
64 | query = query.AddQueryOption("$orderby", orderByString);
65 | }
66 |
67 | return Task.Factory.FromAsync>(query.BeginExecute, query.EndExecute, null)
68 | .ContinueWith(t => (QueryOperationResponse)t.Result, TaskContinuationOptions.ExecuteSynchronously);
69 | }
70 |
71 | private string CreateOrderByString(IList sortDescriptions)
72 | {
73 | var sb = new StringBuilder();
74 |
75 | if (sortDescriptions != null)
76 | {
77 | foreach (var sortDescription in sortDescriptions)
78 | {
79 | if (sb.Length > 0)
80 | {
81 | sb.Append(",");
82 | }
83 |
84 | sb.Append(sortDescription.PropertyName + " " +
85 | (sortDescription.Direction == ListSortDirection.Ascending ? "asc" : "desc"));
86 | }
87 | }
88 |
89 | return sb.ToString();
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/VirtualCollection/Demo/Schedulers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Threading.Tasks;
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 |
13 | namespace VirtualCollection.Demo
14 | {
15 | public static class Schedulers
16 | {
17 | public static TaskScheduler UIThread { get; set; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/VirtualCollection/Demo/StringToImageConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Net;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 | using System.Windows.Data;
7 | using System.Windows.Documents;
8 | using System.Windows.Ink;
9 | using System.Windows.Input;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Animation;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace VirtualCollection.Demo
16 | {
17 | public class StringToImageConverter : IValueConverter
18 | {
19 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
20 | {
21 | var url = value as string;
22 | if (string.IsNullOrEmpty(url))
23 | {
24 | return null;
25 | }
26 |
27 | try
28 | {
29 | var uri = new Uri(url);
30 | var bitmap = new BitmapImage(uri) { CreateOptions = BitmapCreateOptions.DelayCreation};
31 | return bitmap;
32 | }
33 | catch (UriFormatException)
34 | {
35 | return null;
36 | }
37 | }
38 |
39 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
40 | {
41 | throw new NotImplementedException();
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/VirtualCollection/Framework/Behaviors/NotifyViewModelOfLifeCycleEvents.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Interactivity;
3 | using VirtualCollection.Framework.MVVM;
4 |
5 | namespace VirtualCollection.Framework.Behaviors
6 | {
7 | public class NotifyViewModelOfLifeCycleEvents : Behavior
8 | {
9 | protected override void OnAttached()
10 | {
11 | base.OnAttached();
12 |
13 | AssociatedObject.Loaded += HandleLoaded;
14 | AssociatedObject.Unloaded += HandleUnloaded;
15 | }
16 |
17 | protected override void OnDetaching()
18 | {
19 | base.OnDetaching();
20 |
21 | AssociatedObject.Loaded -= HandleLoaded;
22 | AssociatedObject.Unloaded -= HandleUnloaded;
23 | }
24 |
25 | private void HandleLoaded(object sender, RoutedEventArgs e)
26 | {
27 | if (ViewModel != null)
28 | {
29 | ViewModel.NotifyLoaded();
30 | }
31 | }
32 |
33 | private void HandleUnloaded(object sender, RoutedEventArgs e)
34 | {
35 | if (ViewModel != null)
36 | {
37 | ViewModel.NotifyUnloaded();
38 | }
39 | }
40 |
41 | private IViewModel ViewModel
42 | {
43 | get { return AssociatedObject.DataContext as IViewModel; }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/VirtualCollection/Framework/Converters/StringValueConversion.cs:
--------------------------------------------------------------------------------
1 | namespace VirtualCollection.Framework.Converters
2 | {
3 | public class StringValueConversion
4 | {
5 | public string When { get; set; }
6 |
7 | public object Then { get; set; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/VirtualCollection/Framework/Converters/StringValueConversionCollection.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 |
3 | namespace VirtualCollection.Framework.Converters
4 | {
5 | public class StringValueConversionCollection : Collection
6 | {
7 |
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/VirtualCollection/Framework/Converters/StringValueToObjectConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 | using System.Linq;
5 |
6 | namespace VirtualCollection.Framework.Converters
7 | {
8 | public class StringValueToObjectConverter : IValueConverter
9 | {
10 | private StringValueConversionCollection conversions;
11 |
12 | public StringValueConversionCollection Conversions
13 | {
14 | get { return conversions ?? (conversions = new StringValueConversionCollection()); }
15 | set { conversions = value; }
16 | }
17 |
18 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
19 | {
20 | if (value == null)
21 | {
22 | return null;
23 | }
24 |
25 | var selector = value.ToString();
26 |
27 | var conversion = Conversions.FirstOrDefault(c => c.When == selector);
28 |
29 | return conversion != null ? conversion.Then : null;
30 | }
31 |
32 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
33 | {
34 | throw new NotImplementedException();
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/VirtualCollection/Framework/Extensions/INotifyPropertyChangedExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Linq.Expressions;
4 | using System.Net;
5 | using System.Reactive;
6 | using System.Reactive.Linq;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Documents;
10 | using System.Windows.Ink;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Animation;
14 | using System.Windows.Shapes;
15 |
16 | namespace VirtualCollection.Framework.Extensions
17 | {
18 | public static class INotifyPropertyChangedExtensions
19 | {
20 | public static IObservable ObservePropertyChanged(this INotifyPropertyChanged source, Expression> propertyExpression)
21 | {
22 | return ObservePropertyChanged(source, propertyExpression.GetPropertyName());
23 | }
24 |
25 | public static IObservable ObservePropertyChanged(this INotifyPropertyChanged source, string property)
26 | {
27 | return Observable.FromEvent(
28 | h => (sender, e) => h(e),
29 | h => source.PropertyChanged += h,
30 | h => source.PropertyChanged -= h)
31 | .Where(e => e.PropertyName == property)
32 | .Select(_ => Unit.Default);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/VirtualCollection/Framework/Extensions/SymbolExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using System.Reflection;
4 |
5 | namespace VirtualCollection.Framework.Extensions
6 | {
7 | public static class SymbolExtensions
8 | {
9 | ///
10 | /// Gets the PropertyInfo for the last property access in an expression
11 | ///
12 | ///
13 | ///
14 | ///
15 | public static PropertyInfo GetPropertyInfo(this Expression> expression)
16 | {
17 | var memberExpression = expression.Body as MemberExpression;
18 | if (memberExpression == null)
19 | {
20 | throw new InvalidOperationException("expression must consist of a property access");
21 | }
22 |
23 | var propertyInfo = memberExpression.Member as PropertyInfo;
24 | if (propertyInfo == null)
25 | {
26 | throw new InvalidOperationException("expression must consist of a property access");
27 | }
28 |
29 | return propertyInfo;
30 | }
31 |
32 | public static string GetPropertyName(this Expression> expression)
33 | {
34 | return GetPropertyInfo(expression).Name;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/VirtualCollection/Framework/MVVM/ActionCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace VirtualCollection.Framework.MVVM
4 | {
5 | public class ActionCommand : CommandBase
6 | {
7 | private readonly Action