Merge remote-tracking branch 'origin/master' into dotMorten/DesignAssembly

# Conflicts:
#	Directory.Build.props
This commit is contained in:
Morten Nielsen 2017-10-10 23:08:47 -07:00
Родитель 26ec49aacf 596ef812bc
Коммит cbd23fdc70
72 изменённых файлов: 1688 добавлений и 1816 удалений

63
.github/ISSUE_TEMPLATE.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
<!--
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.
-->
## I'm submitting a...
<!-- Check one of the following options with "x" -->
```
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report <!-- Please search GitHub for a similar issue or PR before submitting -->
[ ] Feature request <!-- Please file a UserVoice request and include the link below https://wpdev.uservoice.com/forums/110705-universal-windows-platform/category/193402-uwp-community-toolkit -->
[ ] Sample app request
[ ] Documentation issue or request
[ ] Question of Support request => Please do not submit support request here, instead see https://github.com/Microsoft/UWPCommunityToolkit/blob/master/contributing.md#question
```
## UserVoice link
<!-- If requesting new functionality -->
## Current behavior
<!-- Describe how the issue manifests. -->
## Expected behavior
<!-- Describe what the desired behavior would be. -->
## Minimal reproduction of the problem with instructions
<!--
For bug reports please provide a *MINIMAL REPRO PROJECT* and the *STEPS TO REPRODUCE*
-->
## Environment
<!-- For bug reports Check one or more of the following options with "x" -->
```
Nuget Package(s):
Package Version(s):
Windows 10 Build Number:
- [ ] Anniversary Update (14393)
- [ ] Creators Update (15063)
- [ ] Insider Build (xxxxx)
App min and target version:
- [ ] Anniversary Update (14393)
- [ ] Creators Update (15063)
- [ ] Insider Build (xxxxx)
Device form factor:
- [ ] Desktop
- [ ] Mobile
- [ ] Xbox
- [ ] Surface Hub
- [ ] IoT
Visual Studio
- [ ] 2017 15.3
- [ ] 2017 15.4
```

46
.github/PULL_REQUEST_TEMPLATE.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,46 @@
Issue: #
<!-- Link to relevant issue. All PRs should be asociated with an issue -->
## PR Type
What kind of change does this PR introduce?
<!-- Please check the one that applies to this PR using "x". -->
```
[ ] Bugfix
[ ] Feature
[ ] Code style update (formatting)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build or CI related changes
[ ] Documentation content changes
[ ] Sample app changes
[ ] Other... Please describe:
```
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
## PR Checklist
Please check if your PR fulfills the following requirements:
- [ ] Tested code with current [supported SDKs](../readme.md#supported)
- [ ] Docs have been added / updated (for bug fixes / features)
- [ ] Sample in sample app has been added / updated (for bug fixes / features)
- [ ] Tests for the changes have been added (for bug fixes / features) (if applicable)
## What is the new behavior?
## Does this PR introduce a breaking change?
```
[ ] Yes
[ ] No
```
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below.
Please note that breaking changes are likely to be rejected -->
## Other information

1
.gitignore поставляемый
Просмотреть файл

@ -222,3 +222,4 @@ AppPackages
project.lock.json
msbuild.binlog
*.project.lock.json
/build/tools

Просмотреть файл

@ -16,38 +16,57 @@
<DefaultLanguage>en-US</DefaultLanguage>
<IsDesignProject>$(MSBuildProjectName.EndsWith('.Design'))</IsDesignProject>
<IsDesignProject>$(MSBuildProjectName.Contains('.Design'))</IsDesignProject>
<IsTestProject>$(MSBuildProjectName.Contains('Test'))</IsTestProject>
<IsUwpProject Condition="'$(IsDesignProject)' != 'true'">$(MSBuildProjectName.Contains('Uwp'))</IsUwpProject>
<IsSampleProject>$(MSBuildProjectName.Contains('Sample'))</IsSampleProject>
<GenerateDocumentationFile Condition="'$(IsTestProject)' != 'true' and '$(IsSampleProject)' != 'true' and '$(IsDesignProject)' != 'true'">true</GenerateDocumentationFile>
<UwpMetaPackageVersion>5.3.4</UwpMetaPackageVersion>
<DefaultTargetPlatformVersion>15063</DefaultTargetPlatformVersion>
<DefaultTargetPlatformMinVersion>14393</DefaultTargetPlatformMinVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(IsUwpProject)' == 'true'">
<GenerateLibraryLayout>true</GenerateLibraryLayout>
</PropertyGroup>
<Choose>
<When Condition="'$(IsTestProject)' != 'true' and '$(IsSampleProject)' != 'true' and '$(IsDesignProject)' != 'true'">
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
</When>
</Choose>
<ItemGroup Condition="'$(IsTestProject)' != 'true' and '$(SourceLinkEnabled)' != 'false'">
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup Condition="'$(IsTestProject)' != 'true' and '$(IsSampleProject)' != 'true' and '$(IsDesignProject)' != 'true'">
<!--<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="15.3.83" PrivateAssets="all" />-->
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2" PrivateAssets="all" />
<Choose>
<When Condition="'$(IsUwpProject)' == 'true' and '$(IsSampleProject)' != 'true' and '$(IsDesignProject)' != 'true'">
<PropertyGroup>
<GenerateLibraryLayout>true</GenerateLibraryLayout>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MSBuild.Sdk.Extras" Version="1.0.9" PrivateAssets="all" />
</ItemGroup>
</When>
</Choose>
<EmbeddedResource Include="**\*.rd.xml" />
<Page Include="**\*.xaml" Exclude="**\bin\**\*.xaml;**\obj\**\*.xaml" SubType="Designer" Generator="MSBuild:Compile" />
<Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" />
</ItemGroup>
<Choose>
<When Condition="'$(IsTestProject)' != 'true' and '$(SourceLinkEnabled)' != 'false' and '$(IsSampleProject)' != 'true'">
<ItemGroup>
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
</When>
</Choose>
<ItemGroup Condition="'$(IsUwpProject)' == 'true'">
<PackageReference Include="MSBuild.Sdk.Extras" Version="1.0.9" PrivateAssets="all" />
</ItemGroup>
<Choose>
<When Condition="'$(IsTestProject)' != 'true' and '$(IsSampleProject)' != 'true' and '$(IsDesignProject)' != 'true'">
<ItemGroup>
<!--<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="15.3.83" PrivateAssets="all" />-->
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2" PrivateAssets="all" />
<EmbeddedResource Include="**\*.rd.xml" />
<Page Include="**\*.xaml" Exclude="**\bin\**\*.xaml;**\obj\**\*.xaml" SubType="Designer" Generator="MSBuild:Compile" />
<Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" />
</ItemGroup>
</When>
</Choose>
<PropertyGroup>
<NerdbankGitVersioningVersion>2.0.37-beta</NerdbankGitVersioningVersion>

Просмотреть файл

@ -1,23 +1,26 @@
<Project>
<!-- UAP versions for uap10.0 where TPMV isn't implied -->
<PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0' or '$(TargetFramework)' == 'native'">
<TargetPlatformVersion>10.0.$(DefaultTargetPlatformVersion).0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.$(DefaultTargetPlatformMinVersion).0</TargetPlatformMinVersion>
<DebugType>Full</DebugType>
</PropertyGroup>
<Choose>
<When Condition="'$(TargetFramework)' == 'uap10.0' or '$(TargetFramework)' == 'native'">
<!-- UAP versions for uap10.0 where TPMV isn't implied -->
<PropertyGroup>
<TargetPlatformVersion>10.0.$(DefaultTargetPlatformVersion).0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.$(DefaultTargetPlatformMinVersion).0</TargetPlatformMinVersion>
<DebugType>Full</DebugType>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'uap10.0' or '$(TargetFramework)' == 'native'">
<ItemGroup>
<PackageReference Condition="'$(UseUwpMetaPackage)' == 'true'" Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="$(UwpMetaPackageVersion)" />
<PackageReference Condition="'$(UseUwpMetaPackage)' == 'true'" Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="$(UwpMetaPackageVersion)" />
<SDKReference Condition="'$(UseWindowsDesktopSdk)' == 'true' " Include="WindowsDesktop, Version=$(TargetPlatformVersion)">
<Name>Windows Desktop Extensions for the UWP</Name>
</SDKReference>
<SDKReference Condition="'$(UseWindowsMobileSdk)' == 'true' " Include="WindowsMobile, Version=$(TargetPlatformVersion)">
<Name>Windows Mobile Extensions for the UWP</Name>
</SDKReference>
<SDKReference Condition="'$(UseWindowsDesktopSdk)' == 'true' " Include="WindowsDesktop, Version=$(TargetPlatformVersion)">
<Name>Windows Desktop Extensions for the UWP</Name>
</SDKReference>
<SDKReference Condition="'$(UseWindowsMobileSdk)' == 'true' " Include="WindowsMobile, Version=$(TargetPlatformVersion)">
<Name>Windows Mobile Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
</ItemGroup>
</When>
</Choose>
</Project>

Просмотреть файл

@ -144,7 +144,8 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
"System.Devices.Aep.IsPaired",
"System.Devices.Aep.IsPresent",
"System.Devices.Aep.ProtocolId",
"System.Devices.Aep.Bluetooth.Le.IsConnectable"
"System.Devices.Aep.Bluetooth.Le.IsConnectable",
"System.Devices.Aep.SignalStrength"
};
// BT_Code: Currently Bluetooth APIs don't provide a selector to get ALL devices that are both paired and non-paired.
@ -234,7 +235,11 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
/// <param name="deviceInfo">The update device information.</param>
private async void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation deviceInfo)
{
await AddDeviceToList(deviceInfo);
// Protect against race condition if the task runs after the app stopped the deviceWatcher.
if (sender == _deviceWatcher)
{
await AddDeviceToList(deviceInfo);
}
}
/// <summary>
@ -244,31 +249,37 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
/// <param name="deviceInfoUpdate">The update device information.</param>
private async void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
{
ObservableBluetoothLEDevice device = null;
device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
if (device != null)
if (sender == _deviceWatcher)
{
await device.UpdateAsync(deviceInfoUpdate);
}
ObservableBluetoothLEDevice device = null;
if (device == null)
{
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(2)))
device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
if (device != null)
{
var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
await device.UpdateAsync(deviceInfoUpdate);
}
if (unusedDevice != null)
if (device == null)
{
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(2)))
{
_unusedDevices.Remove(unusedDevice);
unusedDevice.Update(deviceInfoUpdate);
var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
if (unusedDevice != null)
{
_unusedDevices.Remove(unusedDevice);
unusedDevice.Update(deviceInfoUpdate);
}
_readerWriterLockSlim.ExitWriteLock();
// The update to the unknown device means we should move it to the Bluetooth LE Device collection.
if (unusedDevice != null)
{
await AddDeviceToList(unusedDevice);
}
}
_readerWriterLockSlim.ExitWriteLock();
// The update to the unknown device means we should move it to the Bluetooth LE Device collection.
await AddDeviceToList(unusedDevice);
}
}
}
@ -280,19 +291,23 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
/// <param name="deviceInfoUpdate">An update of the device.</param>
private async void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
// Protect against race condition if the task runs after the app stopped the deviceWatcher.
if (sender == _deviceWatcher)
{
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
var device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
BluetoothLeDevices.Remove(device);
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
{
var device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
BluetoothLeDevices.Remove(device);
var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
_unusedDevices?.Remove(unusedDevice);
var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
_unusedDevices?.Remove(unusedDevice);
_readerWriterLockSlim.ExitWriteLock();
}
});
_readerWriterLockSlim.ExitWriteLock();
}
});
}
}
/// <summary>
@ -302,9 +317,12 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
/// <param name="args">The args.</param>
private void DeviceWatcher_EnumerationCompleted(DeviceWatcher sender, object args)
{
StopEnumeration();
if (sender == _deviceWatcher)
{
StopEnumeration();
EnumerationCompleted?.Invoke(sender, EventArgs.Empty);
EnumerationCompleted?.Invoke(sender, EventArgs.Empty);
}
}
/// <summary>
@ -318,12 +336,11 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
if (!string.IsNullOrEmpty(deviceInfo?.Name))
{
var device = new ObservableBluetoothLEDevice(deviceInfo);
var connectable = true;
var connectable = (device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable") &&
(bool)device.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"]) ||
(device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsConnected") &&
(bool)device.DeviceInfo.Properties["System.Devices.Aep.IsConnected"]);
if (device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable"))
{
connectable = (bool)device.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"];
}
if (connectable)
{

Просмотреть файл

@ -11,9 +11,12 @@
// ******************************************************************
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
@ -32,6 +35,45 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
/// <seealso cref="System.IEquatable{ObservableBluetoothLEDevice}" />
public class ObservableBluetoothLEDevice : INotifyPropertyChanged, IEquatable<ObservableBluetoothLEDevice>
{
/// <summary>
/// Compares RSSI values between ObservableBluetoothLEDevice. Sorts based on closest to furthest where 0 is unknown
/// and is sorted as furthest away
/// </summary>
public class RSSIComparer : IComparer
{
public int Compare(object x, object y)
{
ObservableBluetoothLEDevice a = x as ObservableBluetoothLEDevice;
ObservableBluetoothLEDevice b = y as ObservableBluetoothLEDevice;
if( a == null || b == null)
{
throw new InvalidOperationException("Compared objects are not ObservableBluetoothLEDevice");
}
// If they're equal
if(a.RSSI == b.RSSI)
{
return 0;
}
// RSSI == 0 means we don't know it. Always make that the end.
if(b.RSSI == 0)
{
return -1;
}
if(a.RSSI < b.RSSI || a.RSSI == 0)
{
return 1;
}
else
{
return -1;
}
}
}
/// <summary>
/// Source for <see cref="BluetoothLEDevice" />
/// </summary>
@ -71,7 +113,17 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
/// result of finding all the services
/// </summary>
private GattDeviceServicesResult _result;
/// <summary>
/// Queue to store the last 10 observed RSSI values
/// </summary>
private Queue<int> _rssiValue = new Queue<int>(10);
/// <summary>
/// Source for <see cref="RSSI"/>
/// </summary>
private int _rssi;
/// <summary>
/// Source for <see cref="ServiceCount" />
/// </summary>
@ -95,6 +147,8 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
IsPaired = DeviceInfo.Pairing.IsPaired;
LoadGlyph();
this.PropertyChanged += ObservableBluetoothLEDevice_PropertyChanged;
}
/// <summary>
@ -203,6 +257,12 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
{
return _services;
}
private set
{
_services = value;
OnPropertyChanged();
}
}
/// <summary>
@ -265,6 +325,35 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
}
}
/// <summary>
/// Gets the RSSI value of this device
/// </summary>
public int RSSI
{
get
{
return _rssi;
}
private set
{
if (_rssiValue.Count >= 10)
{
_rssiValue.Dequeue();
}
_rssiValue.Enqueue(value);
int newValue = (int)Math.Round(_rssiValue.Average(), 0);
if (_rssi != newValue)
{
_rssi = newValue;
OnPropertyChanged();
}
}
}
/// <summary>
/// Gets the bluetooth address of this device as a string
/// </summary>
@ -289,6 +378,17 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
return other?.DeviceInfo.Id != null && DeviceInfo.Id == other.DeviceInfo.Id;
}
private void ObservableBluetoothLEDevice_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "DeviceInfo")
{
if(DeviceInfo.Properties.ContainsKey("System.Devices.Aep.SignalStrength") && DeviceInfo.Properties["System.Devices.Aep.SignalStrength"] != null)
{
RSSI = (int)DeviceInfo.Properties["System.Devices.Aep.SignalStrength"];
}
}
}
/// <summary>
/// ConnectAsync to this bluetooth device
/// </summary>
@ -326,6 +426,9 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
if (_result.Status == GattCommunicationStatus.Success)
{
// In case we connected before, clear the service list and recreate it
Services.Clear();
foreach (var serv in _result.Services)
{
Services.Add(new ObservableGattDeviceService(serv));

Просмотреть файл

@ -10,4 +10,9 @@
<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
<ItemGroup>
<None Include="VisualStudioToolsManifest.xml" Pack="true" PackagePath="tools" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,8 @@
<FileList>
<File Reference="Microsoft.Toolkit.Uwp.DeveloperTools.dll">
<ToolboxItems VSCategory="UWP Community Toolkit" BlendCategory="UWP Community Toolkit">
<Item Type="Microsoft.Toolkit.Uwp.DeveloperTools.AlignmentGrid" />
<Item Type="Microsoft.Toolkit.Uwp.DeveloperTools.FocusTracker" />
</ToolboxItems>
</File>
</FileList>

Просмотреть файл

@ -10,10 +10,10 @@
<controls:Carousel x:Name="CarouselControl"
InvertPositive="@[InvertPositive:Bool:True]"
ItemDepth="@[ItemDepth:Slider:300:0-400]"
ItemMargin="@[ItemMargin:Slider:0:0-500]"
ItemRotationX="@[ItemRotationX:Slider:0:0-180]"
ItemRotationY="@[ItemRotationY:Slider:45:0-180]"
ItemRotationZ ="@[ItemRotationZ:Slider:0:0-180]"
ItemMargin="@[ItemMargin:Slider:0:-500-500]"
ItemRotationX="@[ItemRotationX:Slider:0:-180-180]"
ItemRotationY="@[ItemRotationY:Slider:45:-180-180]"
ItemRotationZ ="@[ItemRotationZ:Slider:0:-180-180]"
Orientation="@[Orientation:Enum:Orientation.Horizontal]"
SelectedIndex="@[SelectedIndex:String:4]">
<controls:Carousel.EasingFunction>

Просмотреть файл

@ -8,38 +8,40 @@
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Margin="20">
<controls:Expander x:Name="Expander1" VerticalAlignment="Top" Margin="0,0,0,10"
Header="This is the header - expander 1"
HorizontalContentAlignment="Stretch"
Foreground="White"
Background="{Binding Path=BackgroundExpander1.Value, Mode=TwoWay}"
IsExpanded="{Binding Path=IsExpanded1.Value, Mode=TwoWay}"
ExpandDirection="{Binding Path=ExpandDirection1.Value, Mode=TwoWay}">
<Grid Height="250">
<TextBlock HorizontalAlignment="Center"
TextWrapping="Wrap"
Text="This is the content"
VerticalAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}" />
</Grid>
</controls:Expander>
<ScrollViewer>
<StackPanel Margin="20">
<controls:Expander x:Name="Expander1" VerticalAlignment="Top" Margin="0,0,0,10"
Header="This is the header - expander 1"
HorizontalContentAlignment="Stretch"
Foreground="White"
Background="{Binding Path=BackgroundExpander1.Value, Mode=TwoWay}"
IsExpanded="{Binding Path=IsExpanded1.Value, Mode=TwoWay}"
ExpandDirection="{Binding Path=ExpandDirection1.Value, Mode=TwoWay}">
<Grid Height="250">
<TextBlock HorizontalAlignment="Center"
TextWrapping="Wrap"
Text="This is the content"
VerticalAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}" />
</Grid>
</controls:Expander>
<controls:Expander x:Name="Expander2" VerticalAlignment="Top" Margin="0"
Header="This is the header - expander 2"
HorizontalContentAlignment="Stretch"
Foreground="White"
Background="{Binding Path=BackgroundExpander2.Value, Mode=TwoWay}"
IsExpanded="{Binding Path=IsExpanded2.Value, Mode=TwoWay}"
ExpandDirection="{Binding Path=ExpandDirection2.Value, Mode=TwoWay}">
<Grid Height="250">
<TextBlock HorizontalAlignment="Center"
TextWrapping="Wrap"
Text="This is the content"
VerticalAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}" />
</Grid>
</controls:Expander>
</StackPanel>
<controls:Expander x:Name="Expander2" VerticalAlignment="Top" Margin="0"
Header="This is the header - expander 2"
HorizontalContentAlignment="Stretch"
Foreground="White"
Background="{Binding Path=BackgroundExpander2.Value, Mode=TwoWay}"
IsExpanded="{Binding Path=IsExpanded2.Value, Mode=TwoWay}"
ExpandDirection="{Binding Path=ExpandDirection2.Value, Mode=TwoWay}">
<Grid Height="250">
<TextBlock HorizontalAlignment="Center"
TextWrapping="Wrap"
Text="This is the content"
VerticalAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}" />
</Grid>
</controls:Expander>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>

Просмотреть файл

@ -7,36 +7,38 @@
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Margin="20">
<controls:Expander x:Name="Expander1" VerticalAlignment="Top" Margin="0,0,0,10"
Header="This is the header - expander 1"
Foreground="White"
Background="@[BackgroundExpander1:Brush:Gray]"
IsExpanded="@[IsExpanded1:Bool:False]@"
ExpandDirection="@[ExpandDirection1:Enum:ExpandDirection.Down]">
<Grid Height="250">
<TextBlock HorizontalAlignment="Center"
TextWrapping="Wrap"
Text="This is the content"
VerticalAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}" />
</Grid>
</controls:Expander>
<ScrollViewer>
<StackPanel Margin="20">
<controls:Expander x:Name="Expander1" VerticalAlignment="Top" Margin="0,0,0,10"
Header="This is the header - expander 1"
Foreground="White"
Background="@[BackgroundExpander1:Brush:Gray]"
IsExpanded="@[IsExpanded1:Bool:False]@"
ExpandDirection="@[ExpandDirection1:Enum:ExpandDirection.Down]">
<Grid Height="250">
<TextBlock HorizontalAlignment="Center"
TextWrapping="Wrap"
Text="This is the content"
VerticalAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}" />
</Grid>
</controls:Expander>
<controls:Expander x:Name="Expander2" VerticalAlignment="Top" Margin="0"
Header="This is the header - expander 2"
Foreground="White"
Background="@[BackgroundExpander2:Brush:Black]"
IsExpanded="@[IsExpanded2:Bool:True]@"
ExpandDirection="@[ExpandDirection2:Enum:ExpandDirection.Right]">
<Grid Height="250">
<TextBlock HorizontalAlignment="Center"
TextWrapping="Wrap"
Text="This is the content"
VerticalAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}" />
</Grid>
</controls:Expander>
</StackPanel>
<controls:Expander x:Name="Expander2" VerticalAlignment="Top" Margin="0"
Header="This is the header - expander 2"
Foreground="White"
Background="@[BackgroundExpander2:Brush:Black]"
IsExpanded="@[IsExpanded2:Bool:True]@"
ExpandDirection="@[ExpandDirection2:Enum:ExpandDirection.Right]">
<Grid Height="250">
<TextBlock HorizontalAlignment="Center"
TextWrapping="Wrap"
Text="This is the content"
VerticalAlignment="Center"
Style="{StaticResource HeaderTextBlockStyle}" />
</Grid>
</controls:Expander>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>

Просмотреть файл

@ -169,7 +169,7 @@
Header="App ID" />
<HyperlinkButton Margin="0,0,0,15"
Content="Show me how to get this ID"
NavigateUri="http://uwpcommunitytoolkit.readthedocs.io/en/master/services/Facebook/" />
NavigateUri="http://uwpcommunitytoolkit.com/en/master/services/Facebook/" />
<StackPanel Orientation="Horizontal">
<ComboBox x:Name="QueryType"
Header="Type:" />

Просмотреть файл

@ -75,7 +75,7 @@
Orientation="Vertical">
<HyperlinkButton Margin="0,0,0,15"
Content="Show me how to get these values"
NavigateUri="http://uwpcommunitytoolkit.readthedocs.io/en/master/services/Linkedin/" />
NavigateUri="http://uwpcommunitytoolkit.com/en/master/services/Linkedin/" />
<TextBox x:Name="ClientId"
Margin="0,0,0,12"
Header="Client Id:" />

Просмотреть файл

@ -83,7 +83,7 @@
Header="Client Id:" />
<HyperlinkButton Margin="0,0,0,15"
Content="Show me how to get this ID"
NavigateUri="http://uwpcommunitytoolkit.readthedocs.io/en/master/services/MicrosoftGraph/" />
NavigateUri="http://uwpcommunitytoolkit.com/en/master/services/MicrosoftGraph/" />
<Button x:Name="ConnectButton"
Width="75"
Margin="0,10,0,0"

Просмотреть файл

@ -252,7 +252,7 @@
Orientation="Vertical">
<HyperlinkButton Margin="0,0,0,15"
Content="Show me how to get these values"
NavigateUri="http://uwpcommunitytoolkit.readthedocs.io/en/master/services/Twitter/" />
NavigateUri="http://uwpcommunitytoolkit.com/en/master/services/Twitter/" />
<TextBox x:Name="ConsumerKey"
Margin="0,0,0,12"
Header="Consumer Key:" />

Просмотреть файл

@ -200,7 +200,7 @@ namespace Microsoft.Toolkit.Uwp.Services.OneDrive
}
// ParentReference null means is root
if (oneDriveItem.ParentReference != null)
if(oneDriveItem.ParentReference?.Path != null)
{
_path = oneDriveItem.ParentReference.Path.Replace("/drive/root:", string.Empty);
}

Просмотреть файл

@ -41,16 +41,3 @@ using System.Windows;
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.0")]
[assembly: AssemblyFileVersion("2.0.0")]

Просмотреть файл

@ -14,7 +14,7 @@ using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Hosting;
namespace Microsoft.Toolkit.Uwp
namespace Microsoft.Toolkit.Uwp.UI.Controls
{
/// <summary>
/// Internal class used to provide helpers for controls

Просмотреть файл

@ -0,0 +1,74 @@
// ******************************************************************
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
// ******************************************************************
using System;
using System.Reflection;
namespace Microsoft.Toolkit.Uwp.UI.Controls
{
/// <summary>
/// Internal class used to provide helpers for controls
/// </summary>
internal static partial class ControlHelpers
{
private static Lazy<bool> designModeEnabled = new Lazy<bool>(InitializeDesignerMode);
private static Lazy<bool> designMode2Enabled = new Lazy<bool>(InitializeDesignMode2);
public static bool IsRunningInLegacyDesignerMode => ControlHelpers.designModeEnabled.Value && !ControlHelpers.designMode2Enabled.Value;
public static bool IsRunningInEnhancedDesignerMode => ControlHelpers.designModeEnabled.Value && ControlHelpers.designMode2Enabled.Value;
public static bool IsRunningInApplicationRuntimeMode => !ControlHelpers.designModeEnabled.Value;
// Private initializer
private static bool InitializeDesignerMode()
{
return Windows.ApplicationModel.DesignMode.DesignModeEnabled;
}
/// <summary>
/// Used to enable or disable user code inside a XAML designer that targets the Windows 10 Fall Creators Update SDK, or later.
/// </summary>
/// <remarks>
/// <para>
/// Windows.ApplicationModel.DesignMode.DesignModeEnabled returns true when called from user code running inside any version of the XAML designer--regardless of which SDK version you target. This check is recommended for most users.
/// </para><para>
/// Starting with the Windows 10 Fall Creators Update, Visual Studio provides a new XAML designer that targets the Windows 10 Fall Creators Update and later.
/// </para><para>
/// Use Windows.ApplicationModel.DesignMode.DesignMode2Enabled to differentiate code that depends on functionality only enabled for a XAML designer that targets the Windows 10 Fall Creators Update SDK or later.
/// </para>
/// <para>
/// More info here: https://docs.microsoft.com/en-us/uwp/api/Windows.ApplicationModel.DesignMode
/// </para>
/// </remarks>
/// <returns>True if called from code running inside a XAML designer that targets the Windows 10 Fall Creators Update, or later; otherwise false.</returns>
private static bool InitializeDesignMode2()
{
bool designMode2Enabled = false;
try
{
// The reflection below prevents the code to take a direct dependency on Fall Creators Update SDK
if (Windows.Foundation.Metadata.ApiInformation.IsPropertyPresent("Windows.ApplicationModel.DesignMode", "DesignMode2Enabled"))
{
var prop = typeof(Windows.ApplicationModel.DesignMode).GetProperty("DesignMode2Enabled");
if (prop != null && prop.PropertyType == typeof(bool))
{
designMode2Enabled = (bool)prop.GetValue(null);
}
}
}
catch { }
return designMode2Enabled;
}
}
}

Просмотреть файл

@ -10,7 +10,7 @@
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
// ******************************************************************
namespace Microsoft.Toolkit.Uwp
namespace Microsoft.Toolkit.Uwp.UI.Controls
{
/// <summary>
/// Internal class used to provide helpers for controls

Просмотреть файл

@ -67,8 +67,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
/// On platforms not supporting drop shadows, this control has no effect.
/// </remarks>
public static bool IsSupported =>
!DesignMode.DesignModeEnabled &&
ApiInformation.IsTypePresent("Windows.UI.Composition.DropShadow"); // SDK >= 14393
(!ControlHelpers.IsRunningInLegacyDesignerMode) && ApiInformation.IsTypePresent("Windows.UI.Composition.DropShadow"); // SDK >= 14393
/// <summary>
/// Gets DropShadow. Exposes the underlying composition object to allow custom Windows.UI.Composition animations.

Просмотреть файл

@ -41,17 +41,20 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
Element = _gripperDisplay;
}
var hoverWrapper = new GripperHoverWrapper(
CursorBehavior == SplitterCursorBehavior.ChangeOnSplitterHover
? this
: Element,
_resizeDirection,
GripperCursor,
GripperCustomCursorResource);
ManipulationStarted += hoverWrapper.SplitterManipulationStarted;
ManipulationCompleted += hoverWrapper.SplitterManipulationCompleted;
if (_hoverWrapper == null)
{
var hoverWrapper = new GripperHoverWrapper(
CursorBehavior == SplitterCursorBehavior.ChangeOnSplitterHover
? this
: Element,
_resizeDirection,
GripperCursor,
GripperCustomCursorResource);
ManipulationStarted += hoverWrapper.SplitterManipulationStarted;
ManipulationCompleted += hoverWrapper.SplitterManipulationCompleted;
_hoverWrapper = hoverWrapper;
_hoverWrapper = hoverWrapper;
}
}
private void CreateGripperDisplay()

Просмотреть файл

@ -30,7 +30,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
nameof(Element),
typeof(UIElement),
typeof(GridSplitter),
new PropertyMetadata(default(UIElement)));
new PropertyMetadata(default(UIElement), OnElementPropertyChanged));
/// <summary>
/// Identifies the <see cref="ResizeDirection"/> dependency property.
@ -223,5 +223,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
? gridSplitter
: gridSplitter.Element);
}
private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var gridSplitter = (GridSplitter)d;
gridSplitter._hoverWrapper?.UpdateHoverElement(gridSplitter.CursorBehavior ==
SplitterCursorBehavior.ChangeOnSplitterHover
? gridSplitter
: gridSplitter.Element);
}
}
}

Просмотреть файл

@ -15,6 +15,10 @@
<ProjectReference Include="..\Microsoft.Toolkit.Uwp.UI.Animations\Microsoft.Toolkit.Uwp.UI.Animations.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="VisualStudioToolsManifest.xml" Pack="true" PackagePath="tools" />
</ItemGroup>
<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
</Project>

Просмотреть файл

@ -619,7 +619,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
scale.Data = pg;
}
if (!DesignMode.DesignModeEnabled)
if (!ControlHelpers.IsRunningInLegacyDesignerMode)
{
OnFaceChanged(radialGauge);
}
@ -628,7 +628,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
private static void OnFaceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!DesignMode.DesignModeEnabled)
if (!ControlHelpers.IsRunningInLegacyDesignerMode)
{
OnFaceChanged(d);
}
@ -639,7 +639,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
RadialGauge radialGauge = (RadialGauge)d;
var container = radialGauge.GetTemplateChild(ContainerPartName) as Grid;
if (container == null || DesignMode.DesignModeEnabled)
if (container == null || ControlHelpers.IsRunningInLegacyDesignerMode)
{
// Bad template.
return;

Просмотреть файл

@ -471,9 +471,14 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
var rangeSelector = d as RangeSelector;
if (rangeSelector == null)
{
return;
}
rangeSelector._minSet = true;
if (rangeSelector == null || !rangeSelector._valuesAssigned)
if (!rangeSelector._valuesAssigned)
{
return;
}
@ -530,9 +535,14 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
var rangeSelector = d as RangeSelector;
if (rangeSelector == null)
{
return;
}
rangeSelector._maxSet = true;
if (rangeSelector == null || !rangeSelector._valuesAssigned)
if (!rangeSelector._valuesAssigned)
{
return;
}

Просмотреть файл

@ -242,13 +242,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
_translate.X = _translate.Y = 0;
}
if (_currentElement != null)
if (_currentElement != null && _nextElement != null)
{
_currentElement.DataContext = _nextElement.DataContext;
}
if (_nextElement != null)
{
_nextElement.DataContext = GetNext(); // Preload the next tile
}
};

Просмотреть файл

@ -218,8 +218,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
/// <remarks>
/// On platforms not supporting Composition, this <See cref="UIStrategy"/> is automaticaly set to PureXaml.
/// </remarks>
public static bool IsCompositionSupported =>
ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 3); // SDK >= 14393
public static bool IsCompositionSupported => !ControlHelpers.IsRunningInLegacyDesignerMode &&
ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 3); // SDK >= 14393
/// <summary>
/// Initializes a new instance of the <see cref="TileControl"/> class.
@ -291,12 +291,14 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
if (currentStrategy == null)
{
if (DesignMode.DesignModeEnabled == true || IsCompositionSupported == false)
if (!IsCompositionSupported)
{
currentStrategy = UIStrategy.PureXaml;
}
currentStrategy = UIStrategy.Composition;
else
{
currentStrategy = UIStrategy.Composition;
}
}
return currentStrategy.Value;
@ -388,7 +390,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
private async Task<bool> LoadImageBrush(Uri uri)
{
if (DesignMode.DesignModeEnabled)
if (ControlHelpers.IsRunningInLegacyDesignerMode)
{
return false;
}
@ -506,7 +508,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
var control = d as TileControl;
await control.RefreshContainerTileLocked();
await control.CreateModuloExpression(control._scrollviewer);
if (control.Strategy == UIStrategy.Composition)
{
await control.CreateModuloExpression(control._scrollviewer);
}
}
/// <inheritdoc/>

Просмотреть файл

@ -0,0 +1,37 @@
<FileList>
<File Reference="Microsoft.Toolkit.Uwp.UI.Controls.dll">
<ToolboxItems VSCategory="UWP Community Toolkit" BlendCategory="UWP Community Toolkit">
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.AdaptiveGridView" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.BladeItem" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.BladeView" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.Carousel" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.CarouselPanel" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.DropShadowPanel" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.Expander" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.GridSplitter" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.HamburgerMenu" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.HeaderedTextBlock" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.ImageEx" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.ImageExBase" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.MarkdownTextBlock" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.MasterDetailsView" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.Menu" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.MenuItem" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.OrbitView" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.OrbitViewItem" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.OrbitViewPanel" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.PullToRefreshListView" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.RadialGauge" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.RadialProgressBar" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.RangeSelector" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.RotatorTile" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.RoundImageEx" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.ScrollHeader" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.SlidableListItem" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.SurfaceDialTextboxHelper" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.TextToolbar" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.TileControl" />
<Item Type="Microsoft.Toolkit.Uwp.UI.Controls.WrapPanel" />
</ToolboxItems>
</File>
</FileList>

Просмотреть файл

@ -25,6 +25,7 @@ namespace Microsoft.Toolkit.Uwp.UI
{
private int _maxItemCount;
private ConcurrentDictionary<string, InMemoryStorageItem<T>> _inMemoryStorage = new ConcurrentDictionary<string, InMemoryStorageItem<T>>();
private object _settingMaxItemCountLocker = new object();
/// <summary>
/// Gets or sets the maximum count of Items that can be stored in this InMemoryStorage instance.
@ -45,7 +46,7 @@ namespace Microsoft.Toolkit.Uwp.UI
_maxItemCount = value;
lock (this)
lock (_settingMaxItemCountLocker)
{
EnsureStorageBounds(value);
}

Просмотреть файл

@ -22,7 +22,7 @@ init:
- ps: git config --global core.autocrlf true
build_script:
- ps: .\build\build.ps1 SignNuGet
- ps: .\build\build.ps1 -target=SignNuGet
artifacts:
- path: .\bin\nupkg\*.nupkg

Просмотреть файл

@ -1,26 +0,0 @@
$baseDir = Resolve-Path ..
$buildDir = "$baseDir\build"
$toolsDir = "$baseDir\build\tools"
$binDir = "$baseDir\bin"
$tempDir = "$binDir\temp"
$binariesDir = "$binDir\binaries"
$nupkgDir = "$binDir\nupkg"
$nuget = "$toolsDir\nuget\nuget.exe"
$xamlstyler = "$tempDir\XamlStyler.Console\tools\xstyler.exe"
if(!(Test-Path $xamlstyler)){
.$nuget install -excludeversion xamlstyler.console -outputdirectory $tempDir
}
$stylerfile = "$baseDir\settings.xamlstyler"
$Dir = Get-ChildItem -Path $baseDir -recurse
$List = $Dir | where {$_.Extension -eq ".xaml" -and $_.FullName -notmatch 'obj' }
$List | ForEach-Object {
$filePath = $_.FullName
& $xamlstyler -f "$filePath" -c "$stylerfile"
}

258
build/build.cake Normal file
Просмотреть файл

@ -0,0 +1,258 @@
#addin "Cake.FileHelpers"
#addin "Cake.Powershell"
using System;
using System.Linq;
using System.Text.RegularExpressions;
//////////////////////////////////////////////////////////////////////
// ARGUMENTS
//////////////////////////////////////////////////////////////////////
var target = Argument("target", "Default");
//////////////////////////////////////////////////////////////////////
// VERSIONS
//////////////////////////////////////////////////////////////////////
var gitVersioningVersion = "2.0.41";
var signClientVersion = "0.9.0";
//////////////////////////////////////////////////////////////////////
// VARIABLES
//////////////////////////////////////////////////////////////////////
var baseDir = MakeAbsolute(Directory("../")).ToString();
var buildDir = baseDir + "/build";
var Solution = baseDir + "/UWP Community Toolkit.sln";
var toolsDir = buildDir + "/tools";
var binDir = baseDir + "/bin";
var nupkgDir = binDir + "/nupkg";
var signClientSettings = MakeAbsolute(File("SignClientSettings.json")).ToString();
var signClientSecret = EnvironmentVariable("SignClientSecret");
var signClientAppPath = toolsDir + "/SignClient/Tools/netcoreapp2.0/SignClient.dll";
var styler = toolsDir + "/XamlStyler.Console/tools/xstyler.exe";
var stylerFile = baseDir + "/settings.xamlstyler";
var versionClient = toolsDir + "/nerdbank.gitversioning/tools/Get-Version.ps1";
string Version = null;
var name = "UWP Community Toolkit";
var address = "https://developer.microsoft.com/en-us/windows/uwp-community-toolkit";
//////////////////////////////////////////////////////////////////////
// METHODS
//////////////////////////////////////////////////////////////////////
void VerifyHeaders(bool Replace)
{
var header = FileReadText("header.txt") + "\r\n";
bool hasMissing = false;
Func<IFileSystemInfo, bool> exclude_objDir =
fileSystemInfo => !fileSystemInfo.Path.Segments.Contains("obj");
var files = GetFiles(baseDir + "/**/*.cs", exclude_objDir).Where(file =>
{
var path = file.ToString();
return !(path.EndsWith(".g.cs") || path.EndsWith(".i.cs") || System.IO.Path.GetFileName(path).Contains("TemporaryGeneratedFile"));
});
Information("\nChecking " + files.Count() + " file header(s)");
foreach(var file in files)
{
var oldContent = FileReadText(file);
var rgx = new Regex("^(//.*\r?\n|\r?\n)*");
var newContent = header + rgx.Replace(oldContent, "");
if(!newContent.Equals(oldContent, StringComparison.Ordinal))
{
if(Replace)
{
Information("\nUpdating " + file + " header...");
FileWriteText(file, newContent);
}
else
{
Error("\nWrong/missing header on " + file);
hasMissing = true;
}
}
}
if(!Replace && hasMissing)
{
throw new Exception("Please run '.\\build.ps1 -target=UpdateHeaders' and commit the changes.");
}
}
//////////////////////////////////////////////////////////////////////
// DEFAULT TASK
//////////////////////////////////////////////////////////////////////
Task("Clean")
.Description("Clean the output folder")
.Does(() =>
{
if(DirectoryExists(binDir))
{
Information("\nCleaning Working Directory");
CleanDirectory(binDir);
}
else
{
CreateDirectory(binDir);
}
});
Task("Verify")
.Description("Run pre-build verifications")
.IsDependentOn("Clean")
.Does(() =>
{
VerifyHeaders(false);
});
Task("Version")
.Description("Updates the version information in all Projects")
.IsDependentOn("Verify")
.Does(() =>
{
Information("\nDownloading NerdBank GitVersioning...");
var installSettings = new NuGetInstallSettings {
ExcludeVersion = true,
Version = gitVersioningVersion,
OutputDirectory = toolsDir
};
NuGetInstall(new []{"nerdbank.gitversioning"}, installSettings);
Information("\nRetrieving version...");
var results = StartPowershellFile(versionClient);
Version = results[1].Properties["NuGetPackageVersion"].Value.ToString();
Information("\nBuild Version: " + Version);
});
Task("Build")
.Description("Build all projects and get the assemblies")
.IsDependentOn("Version")
.Does(() =>
{
Information("\nBuilding Solution");
var buildSettings = new MSBuildSettings
{
MaxCpuCount = 0
}
.SetConfiguration("Release")
.WithTarget("Restore");
// Force a restore again to get proper version numbers https://github.com/NuGet/Home/issues/4337
MSBuild(Solution, buildSettings);
MSBuild(Solution, buildSettings);
EnsureDirectoryExists(nupkgDir);
buildSettings = new MSBuildSettings
{
MaxCpuCount = 0
}
.SetConfiguration("Release")
.WithTarget("Build")
.WithProperty("GenerateLibraryLayout", "true")
.WithProperty("PackageOutputPath", nupkgDir)
.WithProperty("GeneratePackageOnBuild", "true");
MSBuild(Solution, buildSettings);
});
Task("SignNuGet")
.Description("Sign the NuGet packages with the Code Signing service")
.IsDependentOn("Build")
.Does(() =>
{
if(!string.IsNullOrWhiteSpace(signClientSecret))
{
Information("\nDownloading Sign Client...");
var installSettings = new NuGetInstallSettings {
ExcludeVersion = true,
OutputDirectory = toolsDir,
Version = signClientVersion
};
NuGetInstall(new []{"SignClient"}, installSettings);
var packages = GetFiles(nupkgDir + "/*.nupkg");
Information("\n Signing " + packages.Count() + " Packages");
foreach(var package in packages)
{
Information("\nSubmitting " + package + " for signing...");
var arguments = new ProcessArgumentBuilder()
.AppendQuoted(signClientAppPath)
.Append("sign")
.AppendSwitchQuotedSecret("-s", signClientSecret)
.AppendSwitchQuoted("-c", signClientSettings)
.AppendSwitchQuoted("-i", MakeAbsolute(package).FullPath)
.AppendSwitchQuoted("-n", name)
.AppendSwitchQuoted("-d", name)
.AppendSwitchQuoted("-u", address);
// Execute Signing
var result = StartProcess("dotnet", new ProcessSettings { Arguments = arguments });
if(result != 0)
{
throw new InvalidOperationException("Signing failed!");
}
Information("\nFinished signing " + package);
}
}
else
{
Warning("\nClient Secret not found, not signing packages...");
}
});
//////////////////////////////////////////////////////////////////////
// TASK TARGETS
//////////////////////////////////////////////////////////////////////
Task("Default")
.IsDependentOn("Build");
Task("UpdateHeaders")
.Description("Updates the headers in *.cs files")
.Does(() =>
{
VerifyHeaders(true);
});
Task("StyleXaml")
.Description("Ensures XAML Formatting is Clean")
.Does(() =>
{
Information("\nDownloading XamlStyler...");
var installSettings = new NuGetInstallSettings {
ExcludeVersion = true,
OutputDirectory = toolsDir
};
NuGetInstall(new []{"xamlstyler.console"}, installSettings);
Func<IFileSystemInfo, bool> exclude_objDir =
fileSystemInfo => !fileSystemInfo.Path.Segments.Contains("obj");
var files = GetFiles(baseDir + "/**/*.xaml", exclude_objDir);
Information("\nChecking " + files.Count() + " file(s) for XAML Structure");
foreach(var file in files)
{
StartProcess(styler, "-f \"" + file + "\" -c \"" + stylerFile + "\"");
}
});
//////////////////////////////////////////////////////////////////////
// EXECUTION
//////////////////////////////////////////////////////////////////////
RunTarget(target);

Просмотреть файл

@ -1,42 +1,186 @@
param(
[string]$Task = "default",
[hashtable] $Parameters = @{},
[hashtable] $Properties = @{},
[switch]$Help
##########################################################################
# This is the Cake bootstrapper script for PowerShell.
# This file was downloaded from https://github.com/cake-build/resources
# Feel free to change this file to fit your needs.
##########################################################################
<#
.SYNOPSIS
This is a Powershell script to bootstrap a Cake build.
.DESCRIPTION
This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
and execute your Cake build script with the parameters you provide.
.PARAMETER Target
The build script target to run.
.PARAMETER Configuration
The build configuration to use.
.PARAMETER Verbosity
Specifies the amount of information to be displayed.
.PARAMETER Experimental
Tells Cake to use the latest Roslyn release.
.PARAMETER WhatIf
Performs a dry run of the build script.
No tasks will be executed.
.PARAMETER Mono
Tells Cake to use the Mono scripting engine.
.PARAMETER SkipToolPackageRestore
Skips restoring of packages.
.PARAMETER ScriptArgs
Remaining arguments are added here.
.LINK
https://cakebuild.net
#>
[CmdletBinding()]
Param(
[string]$Target = "Default",
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
[string]$Verbosity = "Verbose",
[switch]$Experimental,
[Alias("DryRun","Noop")]
[switch]$WhatIf,
[switch]$Mono,
[switch]$SkipToolPackageRestore,
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
[string[]]$ScriptArgs
)
$path = Split-Path -Parent $MyInvocation.MyCommand.Definition
Import-Module "$path\tools\psake\psake.psm1"
try
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
function MD5HashFile([string] $filePath)
{
if ($Help){
try {
Get-Help $MyInvocation.MyCommand.Definition -full
Write-Host "Available build tasks:"
Invoke-psake -nologo -docs
}
catch {
}
return
}
Invoke-psake "$path/default.ps1" -task $Task -properties $Properties -parameters $Parameters -nologo
if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
{
return $null
}
if ($psake.build_success -eq $false)
{
exit 1
}
else
{
exit 0
}
[System.IO.Stream] $file = $null;
[System.Security.Cryptography.MD5] $md5 = $null;
try
{
$md5 = [System.Security.Cryptography.MD5]::Create()
$file = [System.IO.File]::OpenRead($filePath)
return [System.BitConverter]::ToString($md5.ComputeHash($file))
}
finally
{
if ($file -ne $null)
{
$file.Dispose()
}
}
}
finally
{
Remove-Module psake
}
Write-Host "Preparing to run build script..."
if(!$PSScriptRoot){
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
}
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
# Should we use mono?
$UseMono = "";
if($Mono.IsPresent) {
Write-Verbose -Message "Using the Mono based scripting engine."
$UseMono = "-mono"
}
# Should we use the new Roslyn?
$UseExperimental = "";
if($Experimental.IsPresent -and !($Mono.IsPresent)) {
Write-Verbose -Message "Using experimental version of Roslyn."
$UseExperimental = "-experimental"
}
# Is this a dry run?
$UseDryRun = "";
if($WhatIf.IsPresent) {
$UseDryRun = "-dryrun"
}
# Make sure tools folder exists
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
Write-Verbose -Message "Creating tools directory..."
New-Item -Path $TOOLS_DIR -Type directory | out-null
}
# Make sure that packages.config exist.
if (!(Test-Path $PACKAGES_CONFIG)) {
Write-Verbose -Message "Downloading packages.config..."
try { (New-Object System.Net.WebClient).DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
Throw "Could not download packages.config."
}
}
# Try find NuGet.exe in path if not exists
if (!(Test-Path $NUGET_EXE)) {
Write-Verbose -Message "Trying to find nuget.exe in PATH..."
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) }
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
$NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
}
}
# Try download NuGet.exe if not exists
if (!(Test-Path $NUGET_EXE)) {
Write-Verbose -Message "Downloading NuGet.exe..."
try {
(New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE)
} catch {
Throw "Could not download NuGet.exe."
}
}
# Save nuget.exe path to environment to be available to child processed
$ENV:NUGET_EXE = $NUGET_EXE
# Restore tools from NuGet?
if(-Not $SkipToolPackageRestore.IsPresent) {
Push-Location
Set-Location $TOOLS_DIR
# Check for changes in packages.config and remove installed tools if true.
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
Write-Verbose -Message "Missing or changed package.config hash..."
Remove-Item * -Recurse -Exclude packages.config,nuget.exe
}
Write-Verbose -Message "Restoring tools from NuGet..."
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
if ($LASTEXITCODE -ne 0) {
Throw "An error occured while restoring NuGet tools."
}
else
{
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
}
Write-Verbose -Message ($NuGetOutput | out-string)
Pop-Location
}
# Make sure that Cake has been installed.
if (!(Test-Path $CAKE_EXE)) {
Throw "Could not find Cake.exe at $CAKE_EXE"
}
# Start Cake
Write-Host "Running build script..."
$path = Split-Path -Parent $MyInvocation.MyCommand.Definition
$Script = "$path/build.cake"
Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs"
exit $LASTEXITCODE

Просмотреть файл

@ -1,153 +0,0 @@
$psake.use_exit_on_error = $true
properties {
$baseDir = Resolve-Path ..
$buildDir = "$baseDir\build"
$sourceDir = "$baseDir"
$toolsDir = "$baseDir\build\tools"
$binDir = "$baseDir\bin"
$isAppVeyor = Test-Path -Path env:\APPVEYOR
$tempDir = "$binDir\temp"
$nupkgDir = "$binDir\nupkg"
$nuget = "$toolsDir\nuget\nuget.exe"
$signClientSettings = "$buildDir\SignClientSettings.json"
$hasSignClientSecret = !([string]::IsNullOrEmpty($env:SignClientSecret))
$signClientAppPath = "$tempDir\SignClient\Tools\netcoreapp1.1\SignClient.dll"
}
task default -depends ?
task UpdateHeaders -description "Updates the headers in *.cs files" {
$header = [System.IO.File]::ReadAllText("$buildDir\header.txt")
Get-ChildItem -Path $sourceDir -Filter *.cs -Exclude *generated* -Recurse | % {
$fullFilename = $_.FullName
$filename = $_.Name
$oldContent = [System.IO.File]::ReadAllText($fullFilename)
$newContent = "$header`r`n" + ($oldContent -Replace "^(//.*\r?\n|\r?\n)*", "")
if ($newContent -ne $oldContent) {
WriteColoredOutput -ForegroundColor Green "Updating '$fullFilename' header...`n"
[System.IO.File]::WriteAllText($fullFilename, $newContent, [System.Text.Encoding]::UTF8)
}
}
}
task Clean -description "Clean the output folder" {
if (Test-Path -path $binDir) {
WriteColoredOutput -ForegroundColor Green "Deleting Working Directory...`n"
Remove-Item $binDir -Recurse -Force
}
New-Item -Path $binDir -ItemType Directory | Out-Null
}
task Setup -description "Setup environment" {
New-Item -Path "$tempDir" -ItemType Directory | Out-Null
WriteColoredOutput -ForegroundColor Green "Installing VSWhere NuGet package...`n"
Exec { .$nuget install -excludeversion vswhere -outputdirectory $tempDir } "Error installing VSWhere NuGet package"
WriteColoredOutput -ForegroundColor Green "Executing VSWhere...`n"
[xml]$vsResult = Exec { .$tempDir\vswhere\tools\vswhere.exe -latest -requires Microsoft.Component.MSBuild -format xml } "Error executing VSWhere"
$vsPath = $vsResult.instances.instance.installationPath
$buildToolsPath = "$vsPath\MSBuild\15.0\Bin\"
WriteColoredOutput -ForegroundColor Green "Updating build tools path...`n"
if (-not (Test-Path -path "$buildToolsPath")) {
throw "Path not found: $buildToolsPath"
}
$env:path = "$buildToolsPath;$env:path"
}
task Verify -description "Run pre-build verifications" {
$header = [System.IO.File]::ReadAllText("$buildDir\header.txt")
Get-ChildItem -Path $sourceDir -Filter *.cs -Exclude *generated* -Recurse | % {
$fullFilename = $_.FullName
$filename = $_.Name
$oldContent = [System.IO.File]::ReadAllText($fullFilename)
$newContent = "$header`r`n" + ($oldContent -Replace "^(//.*\r?\n|\r?\n)*", "")
if ($newContent -ne $oldContent) {
WriteColoredOutput -ForegroundColor Yellow "Wrong/missing header on '$fullFilename'"
$raiseError = $true
}
}
if ($raiseError) {
throw "Please run '.\build.ps1 UpdateHeaders' and commit the changes."
}
}
task Version -description "Updates the version entries in AssemblyInfo.cs files" {
WriteColoredOutput -ForegroundColor Green "Downloading GitVersion...`n"
Exec { .$nuget install -excludeversion nerdbank.gitversioning -pre -Version 2.0.37-beta -outputdirectory $tempDir } "Error downloading Nerdbank.GitVersion"
WriteColoredOutput -ForegroundColor Green "Retrieving version...`n"
$versionObj = .$tempDir\nerdbank.gitversioning\tools\Get-Version.ps1
$script:version = $versionObj.NuGetPackageVersion
WriteColoredOutput -ForegroundColor Green "Build version: $script:version`n"
}
task Build -depends Clean, Setup, Verify, Version -description "Build all projects and get the assemblies" {
# Force a restore again to get proper version numbers https://github.com/NuGet/Home/issues/4337
Exec { msbuild "/t:Restore" /p:Configuration=Release /m "$sourceDir\UWP Community Toolkit.sln" } "Error restoring $solutionFile"
Exec { msbuild "/t:Restore" /p:Configuration=Release /m "$sourceDir\UWP Community Toolkit.sln" } "Error restoring $solutionFile"
Exec { msbuild "/t:Build" /p:Configuration=Release "/p:PackageOutputPath=$nupkgDir" /p:GeneratePackageOnBuild=true /p:TreatWarningsAsErrors=false /p:GenerateLibraryLayout=true /m "$sourceDir\UWP Community Toolkit.sln" } "Error building $solutionFile"
}
task SignNuGet -depends Build -description "Sign the NuGet packages with the Code Signing service" {
if($hasSignClientSecret) {
WriteColoredOutput -ForegroundColor Green "Downloading Sign Client...`n"
Exec { .$nuget install -excludeversion SignClient -Version 0.8.0 -outputdirectory $tempDir } "Error downloading Sign Client"
WriteColoredOutput -ForegroundColor Green "Signing NuPkg files...`n"
Get-ChildItem $nupkgDir\*.nupkg | % {
$nupkg = $_.FullName
WriteColoredOutput -ForegroundColor Green "Submitting '$nupkg' for signing...`n"
dotnet $signClientAppPath 'sign' -c $signClientSettings -i $nupkg -s $env:SignClientSecret -n 'UWP Community Toolkit' -d 'UWP Community Toolkit' -u 'https://developer.microsoft.com/en-us/windows/uwp-community-toolkit'
WriteColoredOutput -ForegroundColor Green "Finished signing '$nupkg'`n"
}
} else {
WriteColoredOutput -ForegroundColor Yellow "Client Secret not found, not signing packages...`n"
}
}
task ? -description "Show the help screen" {
WriteDocumentation
}

Просмотреть файл

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Cake" version="0.22.2" />
</packages>

Просмотреть файл

@ -1,53 +0,0 @@
# Helper script for those who want to run psake without importing the module.
# Example run from PowerShell:
# .\psake.ps1 "default.ps1" "BuildHelloWord" "4.0"
# Must match parameter definitions for psake.psm1/invoke-psake
# otherwise named parameter binding fails
param(
[Parameter(Position=0,Mandatory=0)]
[string]$buildFile,
[Parameter(Position=1,Mandatory=0)]
[string[]]$taskList = @(),
[Parameter(Position=2,Mandatory=0)]
[string]$framework,
[Parameter(Position=3,Mandatory=0)]
[switch]$docs = $false,
[Parameter(Position=4,Mandatory=0)]
[System.Collections.Hashtable]$parameters = @{},
[Parameter(Position=5, Mandatory=0)]
[System.Collections.Hashtable]$properties = @{},
[Parameter(Position=6, Mandatory=0)]
[alias("init")]
[scriptblock]$initialization = {},
[Parameter(Position=7, Mandatory=0)]
[switch]$nologo = $false,
[Parameter(Position=8, Mandatory=0)]
[switch]$help = $false,
[Parameter(Position=9, Mandatory=0)]
[string]$scriptPath,
[Parameter(Position=10,Mandatory=0)]
[switch]$detailedDocs = $false
)
# setting $scriptPath here, not as default argument, to support calling as "powershell -File psake.ps1"
if (!$scriptPath) {
$scriptPath = $(Split-Path -parent $MyInvocation.MyCommand.path)
}
# '[p]sake' is the same as 'psake' but $Error is not polluted
remove-module [p]sake
import-module (join-path $scriptPath psake.psm1)
if ($help) {
Get-Help Invoke-psake -full
return
}
if ($buildFile -and (-not(test-path $buildFile))) {
$absoluteBuildFile = (join-path $scriptPath $buildFile)
if (test-path $absoluteBuildFile) {
$buildFile = $absoluteBuildFile
}
}
Invoke-psake $buildFile $taskList $framework $docs $parameters $properties $initialization $nologo $detailedDocs

Просмотреть файл

@ -1,865 +0,0 @@
# psake
# Copyright (c) 2012 James Kovacs
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#Requires -Version 2.0
#-- Public Module Functions --#
# .ExternalHelp psake.psm1-help.xml
function Invoke-Task
{
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)] [string]$taskName
)
Assert $taskName ($msgs.error_invalid_task_name)
$taskKey = $taskName.ToLower()
if ($currentContext.aliases.Contains($taskKey)) {
$taskName = $currentContext.aliases.$taskKey.Name
$taskKey = $taskName.ToLower()
}
$currentContext = $psake.context.Peek()
Assert ($currentContext.tasks.Contains($taskKey)) ($msgs.error_task_name_does_not_exist -f $taskName)
if ($currentContext.executedTasks.Contains($taskKey)) { return }
Assert (!$currentContext.callStack.Contains($taskKey)) ($msgs.error_circular_reference -f $taskName)
$currentContext.callStack.Push($taskKey)
$task = $currentContext.tasks.$taskKey
$precondition_is_valid = & $task.Precondition
if (!$precondition_is_valid) {
WriteColoredOutput ($msgs.precondition_was_false -f $taskName) -foregroundcolor Cyan
} else {
if ($taskKey -ne 'default') {
if ($task.PreAction -or $task.PostAction) {
Assert ($task.Action -ne $null) ($msgs.error_missing_action_parameter -f $taskName)
}
if ($task.Action) {
try {
foreach($childTask in $task.DependsOn) {
Invoke-Task $childTask
}
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$currentContext.currentTaskName = $taskName
& $currentContext.taskSetupScriptBlock
if ($task.PreAction) {
& $task.PreAction
}
if ($currentContext.config.taskNameFormat -is [ScriptBlock]) {
& $currentContext.config.taskNameFormat $taskName
} else {
WriteColoredOutput ($currentContext.config.taskNameFormat -f $taskName) -foregroundcolor Cyan
}
foreach ($variable in $task.requiredVariables) {
Assert ((test-path "variable:$variable") -and ((get-variable $variable).Value -ne $null)) ($msgs.required_variable_not_set -f $variable, $taskName)
}
& $task.Action
if ($task.PostAction) {
& $task.PostAction
}
& $currentContext.taskTearDownScriptBlock
$task.Duration = $stopwatch.Elapsed
} catch {
if ($task.ContinueOnError) {
"-"*70
WriteColoredOutput ($msgs.continue_on_error -f $taskName,$_) -foregroundcolor Yellow
"-"*70
$task.Duration = $stopwatch.Elapsed
} else {
throw $_
}
}
} else {
# no action was specified but we still execute all the dependencies
foreach($childTask in $task.DependsOn) {
Invoke-Task $childTask
}
}
} else {
foreach($childTask in $task.DependsOn) {
Invoke-Task $childTask
}
}
Assert (& $task.Postcondition) ($msgs.postcondition_failed -f $taskName)
}
$poppedTaskKey = $currentContext.callStack.Pop()
Assert ($poppedTaskKey -eq $taskKey) ($msgs.error_corrupt_callstack -f $taskKey,$poppedTaskKey)
$currentContext.executedTasks.Push($taskKey)
}
# .ExternalHelp psake.psm1-help.xml
function Exec
{
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
[Parameter(Position=1,Mandatory=0)][string]$errorMessage = ($msgs.error_bad_command -f $cmd),
[Parameter(Position=2,Mandatory=0)][int]$maxRetries = 0,
[Parameter(Position=3,Mandatory=0)][string]$retryTriggerErrorPattern = $null
)
$tryCount = 1
do {
try {
$global:lastexitcode = 0
& $cmd
if ($lastexitcode -ne 0) {
throw ("Exec: " + $errorMessage)
}
break
}
catch [Exception]
{
if ($tryCount -gt $maxRetries) {
throw $_
}
if ($retryTriggerErrorPattern -ne $null) {
$isMatch = [regex]::IsMatch($_.Exception.Message, $retryTriggerErrorPattern)
if ($isMatch -eq $false) {
throw $_
}
}
Write-Host "Try $tryCount failed, retrying again in 1 second..."
$tryCount++
[System.Threading.Thread]::Sleep([System.TimeSpan]::FromSeconds(1))
}
}
while ($true)
}
# .ExternalHelp psake.psm1-help.xml
function Assert
{
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)]$conditionToCheck,
[Parameter(Position=1,Mandatory=1)]$failureMessage
)
if (!$conditionToCheck) {
throw ("Assert: " + $failureMessage)
}
}
# .ExternalHelp psake.psm1-help.xml
function Task
{
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][string]$name = $null,
[Parameter(Position=1,Mandatory=0)][scriptblock]$action = $null,
[Parameter(Position=2,Mandatory=0)][scriptblock]$preaction = $null,
[Parameter(Position=3,Mandatory=0)][scriptblock]$postaction = $null,
[Parameter(Position=4,Mandatory=0)][scriptblock]$precondition = {$true},
[Parameter(Position=5,Mandatory=0)][scriptblock]$postcondition = {$true},
[Parameter(Position=6,Mandatory=0)][switch]$continueOnError = $false,
[Parameter(Position=7,Mandatory=0)][string[]]$depends = @(),
[Parameter(Position=8,Mandatory=0)][string[]]$requiredVariables = @(),
[Parameter(Position=9,Mandatory=0)][string]$description = $null,
[Parameter(Position=10,Mandatory=0)][string]$alias = $null,
[Parameter(Position=11,Mandatory=0)][string]$maxRetries = 0,
[Parameter(Position=12,Mandatory=0)][string]$retryTriggerErrorPattern = $null
)
if ($name -eq 'default') {
Assert (!$action) ($msgs.error_default_task_cannot_have_action)
}
$newTask = @{
Name = $name
DependsOn = $depends
PreAction = $preaction
Action = $action
PostAction = $postaction
Precondition = $precondition
Postcondition = $postcondition
ContinueOnError = $continueOnError
Description = $description
Duration = [System.TimeSpan]::Zero
RequiredVariables = $requiredVariables
Alias = $alias
MaxRetries = $maxRetries
RetryTriggerErrorPattern = $retryTriggerErrorPattern
}
$taskKey = $name.ToLower()
$currentContext = $psake.context.Peek()
Assert (!$currentContext.tasks.ContainsKey($taskKey)) ($msgs.error_duplicate_task_name -f $name)
$currentContext.tasks.$taskKey = $newTask
if($alias)
{
$aliasKey = $alias.ToLower()
Assert (!$currentContext.aliases.ContainsKey($aliasKey)) ($msgs.error_duplicate_alias_name -f $alias)
$currentContext.aliases.$aliasKey = $newTask
}
}
# .ExternalHelp psake.psm1-help.xml
function Properties {
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][scriptblock]$properties
)
$psake.context.Peek().properties += $properties
}
# .ExternalHelp psake.psm1-help.xml
function Include {
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][string]$fileNamePathToInclude
)
Assert (test-path $fileNamePathToInclude -pathType Leaf) ($msgs.error_invalid_include_path -f $fileNamePathToInclude)
$psake.context.Peek().includes.Enqueue((Resolve-Path $fileNamePathToInclude));
}
# .ExternalHelp psake.psm1-help.xml
function FormatTaskName {
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)]$format
)
$psake.context.Peek().config.taskNameFormat = $format
}
# .ExternalHelp psake.psm1-help.xml
function TaskSetup {
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][scriptblock]$setup
)
$psake.context.Peek().taskSetupScriptBlock = $setup
}
# .ExternalHelp psake.psm1-help.xml
function TaskTearDown {
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][scriptblock]$teardown
)
$psake.context.Peek().taskTearDownScriptBlock = $teardown
}
# .ExternalHelp psake.psm1-help.xml
function Framework {
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][string]$framework
)
$psake.context.Peek().config.framework = $framework
ConfigureBuildEnvironment
}
# .ExternalHelp psake.psm1-help.xml
function Invoke-psake {
[CmdletBinding()]
param(
[Parameter(Position = 0, Mandatory = 0)][string] $buildFile,
[Parameter(Position = 1, Mandatory = 0)][string[]] $taskList = @(),
[Parameter(Position = 2, Mandatory = 0)][string] $framework,
[Parameter(Position = 3, Mandatory = 0)][switch] $docs = $false,
[Parameter(Position = 4, Mandatory = 0)][hashtable] $parameters = @{},
[Parameter(Position = 5, Mandatory = 0)][hashtable] $properties = @{},
[Parameter(Position = 6, Mandatory = 0)][alias("init")][scriptblock] $initialization = {},
[Parameter(Position = 7, Mandatory = 0)][switch] $nologo = $false,
[Parameter(Position = 8, Mandatory = 0)][switch] $detailedDocs = $false
)
try {
if (-not $nologo) {
"psake version {0}`nCopyright (c) 2010-2014 James Kovacs & Contributors`n" -f $psake.version
}
if (!$buildFile) {
$buildFile = $psake.config_default.buildFileName
}
elseif (!(test-path $buildFile -pathType Leaf) -and (test-path $psake.config_default.buildFileName -pathType Leaf)) {
# If the $config.buildFileName file exists and the given "buildfile" isn 't found assume that the given
# $buildFile is actually the target Tasks to execute in the $config.buildFileName script.
$taskList = $buildFile.Split(', ')
$buildFile = $psake.config_default.buildFileName
}
# Execute the build file to set up the tasks and defaults
Assert (test-path $buildFile -pathType Leaf) ($msgs.error_build_file_not_found -f $buildFile)
$psake.build_script_file = get-item $buildFile
$psake.build_script_dir = $psake.build_script_file.DirectoryName
$psake.build_success = $false
$psake.context.push(@{
"taskSetupScriptBlock" = {};
"taskTearDownScriptBlock" = {};
"executedTasks" = new-object System.Collections.Stack;
"callStack" = new-object System.Collections.Stack;
"originalEnvPath" = $env:path;
"originalDirectory" = get-location;
"originalErrorActionPreference" = $global:ErrorActionPreference;
"tasks" = @{};
"aliases" = @{};
"properties" = @();
"includes" = new-object System.Collections.Queue;
"config" = CreateConfigurationForNewContext $buildFile $framework
})
LoadConfiguration $psake.build_script_dir
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
set-location $psake.build_script_dir
LoadModules
$frameworkOldValue = $framework
. $psake.build_script_file.FullName
$currentContext = $psake.context.Peek()
if ($framework -ne $frameworkOldValue) {
writecoloredoutput $msgs.warning_deprecated_framework_variable -foregroundcolor Yellow
$currentContext.config.framework = $framework
}
ConfigureBuildEnvironment
while ($currentContext.includes.Count -gt 0) {
$includeFilename = $currentContext.includes.Dequeue()
. $includeFilename
}
if ($docs -or $detailedDocs) {
WriteDocumentation($detailedDocs)
CleanupEnvironment
return
}
foreach ($key in $parameters.keys) {
if (test-path "variable:\$key") {
set-item -path "variable:\$key" -value $parameters.$key -WhatIf:$false -Confirm:$false | out-null
} else {
new-item -path "variable:\$key" -value $parameters.$key -WhatIf:$false -Confirm:$false | out-null
}
}
# The initial dot (.) indicates that variables initialized/modified in the propertyBlock are available in the parent scope.
foreach ($propertyBlock in $currentContext.properties) {
. $propertyBlock
}
foreach ($key in $properties.keys) {
if (test-path "variable:\$key") {
set-item -path "variable:\$key" -value $properties.$key -WhatIf:$false -Confirm:$false | out-null
}
}
# Simple dot sourcing will not work. We have to force the script block into our
# module's scope in order to initialize variables properly.
. $MyInvocation.MyCommand.Module $initialization
# Execute the list of tasks or the default task
if ($taskList) {
foreach ($task in $taskList) {
invoke-task $task
}
} elseif ($currentContext.tasks.default) {
invoke-task default
} else {
throw $msgs.error_no_default_task
}
WriteColoredOutput ("`n" + $msgs.build_success + "`n") -foregroundcolor Green
WriteTaskTimeSummary $stopwatch.Elapsed
$psake.build_success = $true
} catch {
$currentConfig = GetCurrentConfigurationOrDefault
if ($currentConfig.verboseError) {
$error_message = "{0}: An Error Occurred. See Error Details Below: `n" -f (Get-Date)
$error_message += ("-" * 70) + "`n"
$error_message += "Error: {0}`n" -f (ResolveError $_ -Short)
$error_message += ("-" * 70) + "`n"
$error_message += ResolveError $_
$error_message += ("-" * 70) + "`n"
$error_message += "Script Variables" + "`n"
$error_message += ("-" * 70) + "`n"
$error_message += get-variable -scope script | format-table | out-string
} else {
# ($_ | Out-String) gets error messages with source information included.
$error_message = "Error: {0}: `n{1}" -f (Get-Date), (ResolveError $_ -Short)
}
$psake.build_success = $false
# if we are running in a nested scope (i.e. running a psake script from a psake script) then we need to re-throw the exception
# so that the parent script will fail otherwise the parent script will report a successful build
$inNestedScope = ($psake.context.count -gt 1)
if ( $inNestedScope ) {
throw $_
} else {
if (!$psake.run_by_psake_build_tester) {
WriteColoredOutput $error_message -foregroundcolor Red
}
}
} finally {
CleanupEnvironment
}
}
#-- Private Module Functions --#
function WriteColoredOutput {
param(
[string] $message,
[System.ConsoleColor] $foregroundcolor
)
$currentConfig = GetCurrentConfigurationOrDefault
if ($currentConfig.coloredOutput -eq $true) {
if (($Host.UI -ne $null) -and ($Host.UI.RawUI -ne $null) -and ($Host.UI.RawUI.ForegroundColor -ne $null)) {
$previousColor = $Host.UI.RawUI.ForegroundColor
$Host.UI.RawUI.ForegroundColor = $foregroundcolor
}
}
$message
if ($previousColor -ne $null) {
$Host.UI.RawUI.ForegroundColor = $previousColor
}
}
function LoadModules {
$currentConfig = $psake.context.peek().config
if ($currentConfig.modules) {
$scope = $currentConfig.moduleScope
$global = [string]::Equals($scope, "global", [StringComparison]::CurrentCultureIgnoreCase)
$currentConfig.modules | foreach {
resolve-path $_ | foreach {
"Loading module: $_"
$module = import-module $_ -passthru -DisableNameChecking -global:$global
if (!$module) {
throw ($msgs.error_loading_module -f $_.Name)
}
}
}
""
}
}
function LoadConfiguration {
param(
[string] $configdir = $PSScriptRoot
)
$psakeConfigFilePath = (join-path $configdir "psake-config.ps1")
if (test-path $psakeConfigFilePath -pathType Leaf) {
try {
$config = GetCurrentConfigurationOrDefault
. $psakeConfigFilePath
} catch {
throw "Error Loading Configuration from psake-config.ps1: " + $_
}
}
}
function GetCurrentConfigurationOrDefault() {
if ($psake.context.count -gt 0) {
return $psake.context.peek().config
} else {
return $psake.config_default
}
}
function CreateConfigurationForNewContext {
param(
[string] $buildFile,
[string] $framework
)
$previousConfig = GetCurrentConfigurationOrDefault
$config = new-object psobject -property @{
buildFileName = $previousConfig.buildFileName;
framework = $previousConfig.framework;
taskNameFormat = $previousConfig.taskNameFormat;
verboseError = $previousConfig.verboseError;
coloredOutput = $previousConfig.coloredOutput;
modules = $previousConfig.modules;
moduleScope = $previousConfig.moduleScope;
}
if ($framework) {
$config.framework = $framework;
}
if ($buildFile) {
$config.buildFileName = $buildFile;
}
return $config
}
function ConfigureBuildEnvironment {
$framework = $psake.context.peek().config.framework
if ($framework -cmatch '^((?:\d+\.\d+)(?:\.\d+){0,1})(x86|x64){0,1}$') {
$versionPart = $matches[1]
$bitnessPart = $matches[2]
} else {
throw ($msgs.error_invalid_framework -f $framework)
}
$versions = $null
$buildToolsVersions = $null
switch ($versionPart) {
'1.0' {
$versions = @('v1.0.3705')
}
'1.1' {
$versions = @('v1.1.4322')
}
'2.0' {
$versions = @('v2.0.50727')
}
'3.0' {
$versions = @('v2.0.50727')
}
'3.5' {
$versions = @('v3.5', 'v2.0.50727')
}
'4.0' {
$versions = @('v4.0.30319')
}
{($_ -eq '4.5.1') -or ($_ -eq '4.5.2')} {
$versions = @('v4.0.30319')
$buildToolsVersions = @('14.0', '12.0')
}
'4.6' {
$versions = @('v4.0.30319')
$buildToolsVersions = @('14.0')
}
default {
throw ($msgs.error_unknown_framework -f $versionPart, $framework)
}
}
$bitness = 'Framework'
if ($versionPart -ne '1.0' -and $versionPart -ne '1.1') {
switch ($bitnessPart) {
'x86' {
$bitness = 'Framework'
$buildToolsKey = 'MSBuildToolsPath32'
}
'x64' {
$bitness = 'Framework64'
$buildToolsKey = 'MSBuildToolsPath'
}
{ [string]::IsNullOrEmpty($_) } {
$ptrSize = [System.IntPtr]::Size
switch ($ptrSize) {
4 {
$bitness = 'Framework'
$buildToolsKey = 'MSBuildToolsPath32'
}
8 {
$bitness = 'Framework64'
$buildToolsKey = 'MSBuildToolsPath'
}
default {
throw ($msgs.error_unknown_pointersize -f $ptrSize)
}
}
}
default {
throw ($msgs.error_unknown_bitnesspart -f $bitnessPart, $framework)
}
}
}
$frameworkDirs = @()
if ($buildToolsVersions -ne $null) {
foreach($ver in $buildToolsVersions) {
if (Test-Path "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\$ver") {
$frameworkDirs += (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\$ver" -Name $buildToolsKey).$buildToolsKey
}
}
}
$frameworkDirs = $frameworkDirs + @($versions | foreach { "$env:windir\Microsoft.NET\$bitness\$_\" })
for ($i = 0; $i -lt $frameworkDirs.Count; $i++) {
$dir = $frameworkDirs[$i]
if ($dir -Match "\$\(Registry:HKEY_LOCAL_MACHINE(.*?)@(.*)\)") {
$key = "HKLM:" + $matches[1]
$name = $matches[2]
$dir = (Get-ItemProperty -Path $key -Name $name).$name
$frameworkDirs[$i] = $dir
}
}
$frameworkDirs | foreach { Assert (test-path $_ -pathType Container) ($msgs.error_no_framework_install_dir_found -f $_)}
$env:path = ($frameworkDirs -join ";") + ";$env:path"
# if any error occurs in a PS function then "stop" processing immediately
# this does not effect any external programs that return a non-zero exit code
$global:ErrorActionPreference = "Stop"
}
function CleanupEnvironment {
if ($psake.context.Count -gt 0) {
$currentContext = $psake.context.Peek()
$env:path = $currentContext.originalEnvPath
Set-Location $currentContext.originalDirectory
$global:ErrorActionPreference = $currentContext.originalErrorActionPreference
[void] $psake.context.Pop()
}
}
function SelectObjectWithDefault
{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$true)]
[PSObject]
$InputObject,
[string]
$Name,
$Value
)
process {
if ($_ -eq $null) { $Value }
elseif ($_ | Get-Member -Name $Name) {
$_.$Name
}
elseif (($_ -is [Hashtable]) -and ($_.Keys -contains $Name)) {
$_.$Name
}
else { $Value }
}
}
# borrowed from Jeffrey Snover http://blogs.msdn.com/powershell/archive/2006/12/07/resolve-error.aspx
# modified to better handle SQL errors
function ResolveError
{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$true)]
$ErrorRecord=$Error[0],
[Switch]
$Short
)
process {
if ($_ -eq $null) { $_ = $ErrorRecord }
$ex = $_.Exception
if (-not $Short) {
$error_message = "`nErrorRecord:{0}ErrorRecord.InvocationInfo:{1}Exception:`n{2}"
$formatted_errorRecord = $_ | format-list * -force | out-string
$formatted_invocationInfo = $_.InvocationInfo | format-list * -force | out-string
$formatted_exception = ''
$i = 0
while ($ex -ne $null) {
$i++
$formatted_exception += ("$i" * 70) + "`n" +
($ex | format-list * -force | out-string) + "`n"
$ex = $ex | SelectObjectWithDefault -Name 'InnerException' -Value $null
}
return $error_message -f $formatted_errorRecord, $formatted_invocationInfo, $formatted_exception
}
$lastException = @()
while ($ex -ne $null) {
$lastMessage = $ex | SelectObjectWithDefault -Name 'Message' -Value ''
$lastException += ($lastMessage -replace "`n", '')
if ($ex -is [Data.SqlClient.SqlException]) {
$lastException += "(Line [$($ex.LineNumber)] " +
"Procedure [$($ex.Procedure)] Class [$($ex.Class)] " +
" Number [$($ex.Number)] State [$($ex.State)] )"
}
$ex = $ex | SelectObjectWithDefault -Name 'InnerException' -Value $null
}
$shortException = $lastException -join ' --> '
$header = $null
$current = $_
$header = (($_.InvocationInfo |
SelectObjectWithDefault -Name 'PositionMessage' -Value '') -replace "`n", ' '),
($_ | SelectObjectWithDefault -Name 'Message' -Value ''),
($_ | SelectObjectWithDefault -Name 'Exception' -Value '') |
? { -not [String]::IsNullOrEmpty($_) } |
Select -First 1
$delimiter = ''
if ((-not [String]::IsNullOrEmpty($header)) -and
(-not [String]::IsNullOrEmpty($shortException)))
{ $delimiter = ' [<<==>>] ' }
return "$($header)$($delimiter)Exception: $($shortException)"
}
}
function WriteDocumentation($showDetailed) {
$currentContext = $psake.context.Peek()
if ($currentContext.tasks.default) {
$defaultTaskDependencies = $currentContext.tasks.default.DependsOn
} else {
$defaultTaskDependencies = @()
}
$docs = $currentContext.tasks.Keys | foreach-object {
if ($_ -eq "default") {
return
}
$task = $currentContext.tasks.$_
new-object PSObject -property @{
Name = $task.Name;
Alias = $task.Alias;
Description = $task.Description;
"Depends On" = $task.DependsOn -join ", "
Default = if ($defaultTaskDependencies -contains $task.Name) { $true }
}
}
if ($showDetailed) {
$docs | sort 'Name' | format-list -property Name,Alias,Description,"Depends On",Default
} else {
$docs | sort 'Name' | format-table -autoSize -wrap -property Name,Alias,"Depends On",Default,Description
}
}
function WriteTaskTimeSummary($invokePsakeDuration) {
if ($psake.context.count -gt 0) {
"-" * 70
"Build Time Report"
"-" * 70
$list = @()
$currentContext = $psake.context.Peek()
while ($currentContext.executedTasks.Count -gt 0) {
$taskKey = $currentContext.executedTasks.Pop()
$task = $currentContext.tasks.$taskKey
if ($taskKey -eq "default") {
continue
}
$list += new-object PSObject -property @{
Name = $task.Name;
Duration = $task.Duration
}
}
[Array]::Reverse($list)
$list += new-object PSObject -property @{
Name = "Total:";
Duration = $invokePsakeDuration
}
# using "out-string | where-object" to filter out the blank line that format-table prepends
$list | format-table -autoSize -property Name,Duration | out-string -stream | where-object { $_ }
}
}
DATA msgs {
convertfrom-stringdata @'
error_invalid_task_name = Task name should not be null or empty string.
error_task_name_does_not_exist = Task {0} does not exist.
error_circular_reference = Circular reference found for task {0}.
error_missing_action_parameter = Action parameter must be specified when using PreAction or PostAction parameters for task {0}.
error_corrupt_callstack = Call stack was corrupt. Expected {0}, but got {1}.
error_invalid_framework = Invalid .NET Framework version, {0} specified.
error_unknown_framework = Unknown .NET Framework version, {0} specified in {1}.
error_unknown_pointersize = Unknown pointer size ({0}) returned from System.IntPtr.
error_unknown_bitnesspart = Unknown .NET Framework bitness, {0}, specified in {1}.
error_no_framework_install_dir_found = No .NET Framework installation directory found at {0}.
error_bad_command = Error executing command {0}.
error_default_task_cannot_have_action = 'default' task cannot specify an action.
error_duplicate_task_name = Task {0} has already been defined.
error_duplicate_alias_name = Alias {0} has already been defined.
error_invalid_include_path = Unable to include {0}. File not found.
error_build_file_not_found = Could not find the build file {0}.
error_no_default_task = 'default' task required.
error_loading_module = Error loading module {0}.
warning_deprecated_framework_variable = Warning: Using global variable $framework to set .NET framework version used is deprecated. Instead use Framework function or configuration file psake-config.ps1.
required_variable_not_set = Variable {0} must be set to run task {1}.
postcondition_failed = Postcondition failed for task {0}.
precondition_was_false = Precondition was false, not executing task {0}.
continue_on_error = Error in task {0}. {1}
build_success = Build Succeeded!
'@
}
import-localizeddata -bindingvariable msgs -erroraction silentlycontinue
$script:psake = @{}
$psake.version = "4.4.1" # contains the current version of psake
$psake.context = new-object system.collections.stack # holds onto the current state of all variables
$psake.run_by_psake_build_tester = $false # indicates that build is being run by psake-BuildTester
$psake.config_default = new-object psobject -property @{
buildFileName = "default.ps1";
framework = "4.0";
taskNameFormat = "Executing {0}";
verboseError = $false;
coloredOutput = $true;
modules = $null;
moduleScope = "";
} # contains default configuration, can be overriden in psake-config.ps1 in directory with psake.psm1 or in directory with current build script
$psake.build_success = $false # indicates that the current build was successful
$psake.build_script_file = $null # contains a System.IO.FileInfo for the current build script
$psake.build_script_dir = "" # contains a string with fully-qualified path to current build script
LoadConfiguration
export-modulemember -function Invoke-psake, Invoke-Task, Task, Properties, Include, FormatTaskName, TaskSetup, TaskTearDown, Framework, Assert, Exec -variable psake

Просмотреть файл

@ -10,21 +10,43 @@ You can always add to an API, you cannot ever remove anything from one. If the d
That's why many of the guidelines of this document are obvious and serve only one purpose: Simplicity.
## A good pull request
Every contribution has to come with:
- [Questions](#question)
- [Issues or Bugs](#issue)
- [Submitting a pull request](#pr)
- [Quality assurance for pull requests for XAML controls](#xaml)
- [General rules](#rules)
- [Naming conventions](#naming)
- [Documentation](#documentation)
- [Files and folders](#files)
## <a name="question"></a> Questions
Please do not open issues for general support questions and keep our GitHub issues for bug reports and feature requests. There is a much better chance of getting your question answered on [StackOverflow](https://stackoverflow.com/search?q=uwp+community+toolkit) where questions should be tagged with the tag `uwp-community-toolkit`
## <a name="issue"></a> Found a Bug?
If you find a bug, you can help us by
[submitting an issue](https://github.com/Microsoft/UWPCommunityToolkit/issues). Even better, you can
[submit a Pull Request](#pr) with a fix.
## <a name="pr"></a> Submitting a pull request
For every contribution, you must:
* test your code with the [supported SDKs](readme.md#supported)
* follow the [quality guidance](#xaml), [general rules](#rules) and [naming convention](#naming)
* target master branch (or an appropriate release branch if appropriate for a bug fix)
* If adding a new feature
* Before starting coding, **you should open an uservoice entry** under "UWP Community Toolkit" on [Uservoice](https://wpdev.uservoice.com/forums/110705-universal-windows-platform/category/193402-uwp-community-toolkit) and start discussing with the community to see if your idea/feature is interesting enough.
* Add or update a documentation page in the [documentation folder](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/docs). Once validated your documentation will be visible [here](http://docs.uwpcommunitytoolkit.com/en/master/)
* Add or update a sample for the [Sample app](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp)
* Add or update unit tests (if applicable)
* Before starting coding, **you should open an uservoice entry** under "UWP Community Toolkit" on [Uservoice](https://wpdev.uservoice.com/forums/110705-universal-windows-platform/category/193402-uwp-community-toolkit) and start discussing with the community to see if your idea/feature is interesting enough.
* A documentation page in the [documentation folder](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/docs). Once validated your documentation will be visible [here](http://docs.uwpcommunitytoolkit.com/en/master/)
* A sample for the [Sample app](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp) (If applicable)
* Unit tests (If applicable)
* You tested your code with SDK 14393 and SDK 15063
* PR has to target master branch
PR has to be validated by at least two core members before being merged.
Once merged, you can get a pre-release package of the toolkit by adding this ([Nuget repo](https://dotnet.myget.org/F/uwpcommunitytoolkit/api/v3/index.json) | [Gallery](https://dotnet.myget.org/gallery/uwpcommunitytoolkit)) to your Visual Studio.
## Quality insurance for pull requests for XAML controls
## <a name="xaml"></a> Quality assurance for pull requests for XAML controls
We encourage developers to follow the following guidances when submitting pull requests for controls:
* Your control must be usable and efficient with keyboard only
* Tab order must be logical
@ -40,7 +62,7 @@ You can find more information about these topics [here](https://blogs.msdn.micro
This is to help as part of our effort to build an accessible toolkit (starting with 1.2)
## General rules
## <a name="rules"></a> General rules
* DO NOT require that users perform any extensive initialization before they can start programming basic scenarios.
* DO provide good defaults for all values associated with parameters, options, etc.
@ -55,10 +77,10 @@ This is to help as part of our effort to build an accessible toolkit (starting w
* DO use verbs like GET.
* DO NOT use verbs that are not already used like fetch.
## Naming conventions
## <a name="naming"></a> Naming conventions
* We are following the coding guidelines of [.NET Core Foundational libraries](https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md).
## Documentation
## <a name="documentation"></a> Documentation
* DO NOT expect that your API is so well designed that it needs no documentation. No API is that intuitive.
* DO provide great documentation with all APIs.
* DO use readable and self-documenting identifier names.
@ -66,6 +88,6 @@ This is to help as part of our effort to build an accessible toolkit (starting w
* DO provide strongly typed APIs.
* DO use verbose identifier names.
## Files and folders
## <a name="files"></a> Files and folders
* DO associate no more than one class per file.
* DO use folders to group classes based on features.

Просмотреть файл

@ -0,0 +1,121 @@
---
title: AnimationSet class
author: Vijay-Nirmal
ms.date: 09/01/2017
description: The AnimationSet class defines an object for storing and managing Storyboard and CompositionAnimations for an element
keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, animationset, animationset class
---
# AnimationSet
The AnimationSet class defines an object for storing and managing Storyboard and CompositionAnimations for an element. AnimationSet includes [Blur](\Blur.md), [Fade](\Fade.md), [Light](\Light.md), [Offset](\Offset.md), [Rotate](\Rotate.md), [Saturation](\Saturation.md) and [Scale](\Scale.md) animations. AnimationSet animations is applied to all the XAML elements in its parent control/panel. AnimationSet animations doesn't affect the functionality of the control.
## Syntax
**XAML**
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<interactivity:Interaction.Behaviors>
<interactivity:BehaviorCollection>
<behaviors:Blur Value="10" Duration="2500" AutomaticallyStart="True"/>
<behaviors:Scale ScaleX="2" ScaleY="2" Duration="2500" AutomaticallyStart="True"/>
<!-- Others -->
</interactivity:BehaviorCollection>
</interactivity:Interaction.Behaviors>
```
**C#**
```csharp
var anim = MyUIElement.Light(5).Offset(offsetX: 100, offsetY: 100).Saturation(0.5).Scale(scaleX: 2, scaleY: 2);
anim.SetDurationForAll(2500);
anim.SetDelay(250);
anim.Start();
```
## Sample Output
![AnimationSet animations](../resources/images/Animations/Chaining-Animations-Light-Offset-Saturation-Scale.gif)
## Properties
### EasingType
You can change the way how the animation interpolates between keyframes by defining the EasingType.
| EasingType | Explanation | Graphical Explanation |
| ---------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| Default | Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic | |
| Linear | Creates an animation that accelerates or decelerates linear | |
| Back | Retracts the motion of an animation slightly before it begins to animate in the path indicated | ![BackEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/backease-graph.png) |
| Bounce | Creates a bouncing effect | ![BounceEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/bounceease-graph.png) |
| Circle | Creates an animation that accelerates or decelerates using a circular function | ![CircleEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/circleease-graph.png) |
| Cubic | Creates an animation that accelerates or decelerates using the formula f(t) = t3 | ![CubicEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/cubicease-graph.png) |
| Elastic | Creates an animation that resembles a spring oscillating back and forth until it comes to rest | ![ElasticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/elasticease-graph.png) |
| Quadratic | Creates an animation that accelerates or decelerates using the formula f(t) = t2 | ![QuadraticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quadraticease-graph.png) |
| Quartic | Creates an animation that accelerates or decelerates using the formula f(t) = t4 | ![QuarticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quarticease-graph.png) |
| Quintic | Create an animation that accelerates or decelerates using the formula f(t) = t5 | ![QuinticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quinticease-graph.png) |
| Sine | Creates an animation that accelerates or decelerates using a sine formula | ![SineEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/sineease-graph.png) |
***Note:** EasingType is used only when AnimationSet.UseComposition == false*
***Note:** Blur, Light and Saturation animation don't support easing*
## Examples
- AnimationSet has endless possibility. Here is an example of creating popup effect
**Sample Code**
```csharp
FrameworkElement preElement = null;
private void MyUIElement_PointerEntered(object sender, PointerRoutedEventArgs e)
{
preElement = sender as FrameworkElement;
preElement.Blur(value: 0).Fade(value: 1).Scale(centerX: 100, centerY: 100, easingType: EasingType.Sine);
.SetDurationForAll(500);
.Start();
}
private void MyUIElement_PointerExited(object sender, PointerRoutedEventArgs e)
{
if (preElement != null)
{
preElement.Blur(value: 0).Fade(value: 0.1f).Scale(scaleX: 0.5f, scaleY: 0.5f, centerX: 100, centerY: 100, easingType: EasingType.Sine)
.SetDurationForAll(500);
.Start();
}
}
```
**Sample Output**
![Use Case 1 Output](../resources/images/Animations/AnimationSet/Use-Case-1.gif)
- Use `Then()` to create a successive animation
**Sample Code**
```csharp
MyUIElement.Blur(value: 10).Fade(value: 0.5f)
.Then()
.Fade(value: 1).Scale(scaleX: 2, scaleY: 2, centerX: 100, centerY: 100, easingType: EasingType.Sine)
.SetDurationForAll(2500)
.Start();
```
**Sample Output**
![Use Case 2 Output](../resources/images/Animations/AnimationSet/Use-Case-2.gif)
## Requirements
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API
* [AnimationSet source code](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Animations)

Просмотреть файл

@ -8,75 +8,87 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, blur, blur animat
# Blur
The **Blur animation behavior** selectively blurs a XAML element by increasing or decreasing pixel size.
Sometimes you want an element to appear slightly out of focus, but to be familiar to the user from other locations within an app. Rather than having to rasterize the XAML into an image and apply a blur, you can apply a BlurBehavior to the original element at run time.
**NOTE**: This animation REQUIRES the [Windows 10 Anniversary SDK 14393](https://blogs.windows.com/windowsexperience/2016/07/18/build14393/) 10.0.14393.0 in order for it to work.
The Blur animation blurs a XAML element by increasing or decreasing pixel size. Blur animation is applied to all the XAML elements in its parent control/panel. Blur animation doesn't affect the functionality of the control.
## Syntax
You can either use the blur behavior from your XAML code:
**XAML**
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<interactivity:Interaction.Behaviors>
<interactivity:Interaction.Behaviors>
<behaviors:Blur x:Name="BlurBehavior"
Value="10"
Duration="500"
Delay="250"
AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
Value="10"
Duration="2500"
Delay="250"
AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
```
or directly from code:
**C#**
```csharp
ToolkitLogo.Blur(value: 10, duration: 500, delay: 250);
MyUIElement.Blur(value: 5, duration: 2500, delay: 250).Start();
await MyUIElement.Blur(value: 5, duration: 2500, delay: 250).StartAsync(); //Blur animation can be awaited
```
## Sample Output
![Blur Behavior animation](../resources/images/Animations/Blur/Sample-Output.gif)
## Properties
| Property Name | Type | Description |
| --- | --- | --- |
| Value | double | The amount of Gaussian blur to apply to the pixel |
| Duration | double | The number of milliseconds the animation should run for |
| Delay | double | The number of milliseconds before the animation is started |
## Chaining animations
Behavior animations can also be chained and awaited.
## Examples
```csharp
- Use this to shift the focus to foreground controls.
Element.Rotate(value: 30f, duration: 0.3).StartAsync();
**Sample Code**
```xml
<Grid>
<Grid>
<interactivity:Interaction.Behaviors>
<behaviors:Blur x:Name="BlurBehavior" Value="5" Duration="2500" Delay="0" AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
<!-- XAML Element to be Blurred -->
<!-- Background(even for Transparent background) of this Grid will also be Blurred -->
</Grid>
<!-- Foreground XAML Element -->
</Grid>
```
**Sample Output**
await Element.Rotate(value: 30f, duration: 0.3).StartAsync();
![Use Case 1 Output](../resources/images/Animations/Blur/Use-Case-1.gif)
var anim = element.Rotate(30f).Fade(0.5).Blur(5);
anim.SetDurationForAll(2);
- Use this to create chaining animations with other animations. Visit the [AnimationSet](\AnimationSet.md) documentation for more information.
**Sample Code**
```csharp
var anim = MyUIElement.Blur(5).Fade(0.5f).Rotate(30);
anim.SetDurationForAll(2500);
anim.SetDelay(250);
anim.Completed += animation_completed;
anim.StartAsync();
anim.Start();
```
**Sample Output**
anim.Stop();
![Use Case 2 Output](../resources/images/Animations/Chaining-Animations-Blur-Fade-Rotate.gif)
```
## Sample Project
[Blur Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur)
[Blur Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Blur). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ)
## Example Image
## Requirements
![Blur Behavior animation](../resources/images/Animations-Blur.gif "Blur Behavior")
## Requirements (Windows 10 Device Family)
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, [Windows 10 Anniversary SDK 14393](https://blogs.windows.com/windowsexperience/2016/07/18/build14393/) 10.0.14393.0 |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API
* [Blur source code](https://github.com/Microsoft/UWPCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/Blur.cs)

Просмотреть файл

@ -68,6 +68,8 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, expressions, expr
- [Summary Expression Definition](#curtain-summary-expression-definition)
- [Building with ExpressionNodes](#curtain-building-with-expressionnodes)
- [Final code snippet](#curtain-final-code-snippet)
- [Requirements](#requirements)
- [API](#api)
## <a name="quick-start"></a>Quick Start
@ -1123,12 +1125,13 @@ _tracker.ConfigurePositionYInertiaModifiers(
new InteractionTrackerInertiaModifier[] { modifier });
```
## Requirements (Windows 10 Device Family)
## <a name="requirements"></a>Requirements
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API
## <a name="api"></a>API
* [Expressions source code](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Animations/Expressions)

Просмотреть файл

@ -8,94 +8,89 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, fade, fade animat
# Fade
The **Fade animation behavior** fades objects, in and out, over time.
The Fade animation fades objects, in and out, over time. Fade animation is applied to all the XAML elements in its parent control/panel. Fade animation doesn't affect the functionality of the control.
## Syntax
**XAML**
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<behaviors:Fade x:Name="FadeBehavior>"
Value="0.5"
Duration="1500"
Delay="500"
AutomaticallyStart="True">
</behaviors:Fade>
<interactivity:Interaction.Behaviors>
<behaviors:Fade x:Name="FadeBehavior"
Value="0.5"
Duration="2500"
Delay="250"
AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
```
or directly from code:
**C#**
```csharp
MyRectangle.Fade((float)Value, Duration, Delay);
MyUIElement.Fade(value: 0.5f, duration: 2500, delay: 250, easingType: EasingType.Default).Start();
await MyUIElement.Fade(value: 0.5f, duration: 2500, delay: 250, easingType: EasingType.Default).StartAsync(); //Fade animation can be awaited
```
## Sample Output
![Fade Behavior animation](../resources/images/Animations/Fade/Sample-Output.gif)
## Properties
| Property Name | Type | Description |
| --- | --- | --- |
| Value | float | The amount to fade an element. The value should be between 0.0 and l.0 |
| Duration | double | The number of milliseconds the animation should run for |
| Delay | double | The number of milliseconds before the animation is started |
## Chaining animations
Behavior animations can also be chained and awaited.
### EasingType
```csharp
You can change the way how the animation interpolates between keyframes by defining the EasingType.
Element.Rotate(value: 30f, duration: 0.3).StartAsync();
| EasingType | Explanation | Graphical Explanation |
| ---------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| Default | Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic | |
| Linear | Creates an animation that accelerates or decelerates linear | |
| Back | Retracts the motion of an animation slightly before it begins to animate in the path indicated | ![BackEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/backease-graph.png) |
| Bounce | Creates a bouncing effect | ![BounceEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/bounceease-graph.png) |
| Circle | Creates an animation that accelerates or decelerates using a circular function | ![CircleEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/circleease-graph.png) |
| Cubic | Creates an animation that accelerates or decelerates using the formula f(t) = t3 | ![CubicEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/cubicease-graph.png) |
| Elastic | Creates an animation that resembles a spring oscillating back and forth until it comes to rest | ![ElasticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/elasticease-graph.png) |
| Quadratic | Creates an animation that accelerates or decelerates using the formula f(t) = t2 | ![QuadraticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quadraticease-graph.png) |
| Quartic | Creates an animation that accelerates or decelerates using the formula f(t) = t4 | ![QuarticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quarticease-graph.png) |
| Quintic | Create an animation that accelerates or decelerates using the formula f(t) = t5 | ![QuinticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quinticease-graph.png) |
| Sine | Creates an animation that accelerates or decelerates using a sine formula | ![SineEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/sineease-graph.png) |
await Element.Rotate(value: 30f, duration: 0.3).StartAsync();
***Note:** EasingType is used only when AnimationSet.UseComposition == false*
var anim = element.Rotate(30f).Fade(0.5).Blur(5);
anim.SetDurationForAll(2);
## Examples
- Use this to create chaining animations with other animations. Visit the [AnimationSet](\AnimationSet.md) documentation for more information.
**Sample Code**
```csharp
var anim = MyUIElement.Fade(0.5f).Blur(5).Rotate(30);
anim.SetDurationForAll(2500);
anim.SetDelay(250);
anim.Completed += animation_completed;
anim.StartAsync();
anim.Start();
```
**Sample Output**
anim.Stop();
![Use Case 1 Output](../resources/images/Animations/Chaining-Animations-Blur-Fade-Rotate.gif)
```
## Sample Project
[Fade Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Fade)
[Fade Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Fade). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ).
## EasingType
You can change the way how the animation interpolates between keyframes by defining the EasingType using an optional parameter.
## Requirements
| EasingType | Explanation|
| --- | --- |
| Default | Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic. |
| Linear | Creates an animation that accelerates or decelerates linear. |
| Cubic | Creates an animation that accelerates or decelerates using the formula f(t) = t3. |
| Back | Retracts the motion of an animation slightly before it begins to animate in the path indicated. |
| Bounce | Creates a bouncing effect. |
| Elastic | Creates an animation that resembles a spring oscillating back and forth until it comes to rest.|
| Circle | Creates an animation that accelerates or decelerates using a circular function. |
| Quadratic | Creates an animation that accelerates or decelerates using the formula f(t) = t2. |
| Quartic | Creates an animation that accelerates or decelerates using the formula f(t) = t4. |
| Quintic | Create an animation that accelerates or decelerates using the formula f(t) = t5. |
| Sine | Creates an animation that accelerates or decelerates using a sine formula. |
*Please note that EasingType is used only when AnimationSet.UseComposition == false*
**Example Usage:**
```csharp
MyRectangle.Fade(value: 10, duration: 10, delay: 0, easingType: EasingType.Bounce);
```
## Example Image
![Fade Behavior animation](../resources/images/Animations-Fade.gif "Fade Behavior")
## Requirements (Windows 10 Device Family)
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API
* [Fade source code](https://github.com/Microsoft/UWPCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/Fade.cs)

Просмотреть файл

@ -8,101 +8,72 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, fadeheader, fadeh
# FadeHeader
The **FadeHeader Behavior** fades a ListView or GridView Header UIElement when the user scrolls. The UIElement fades out to 0 opacity when the edge of the Header reaches the edge of the visible bounds of the ListElement.
The FadeHeader fades a ListView or GridView Header UIElement when the user scrolls. The UIElement fades out to 0 opacity when the edge of the Header reaches the edge of the visible bounds of the ListElement.
## Syntax
### XAML Implementation ###
**Implicit usage**:
Automatically detects the Header element by finding the ListViewBase (note: GridView uses ListViewBase)
**XAML**
***Implicit usage***: Automatically detects the Header element by finding the ListViewBase (note: GridView uses ListViewBase)
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<interactivity:Interaction.Behaviors>
<behaviors:FadeHeaderBehavior />
</interactivity:Interaction.Behaviors>
```
**Explicit usage**:
Set the ElementName property using the UIElement of the Header manually
```xml
<interactivity:Interaction.Behaviors>
<behaviors:FadeHeaderBehavior HeaderElement="{Binding ElementName=MyHeaderGrid}" />
</interactivity:Interaction.Behaviors>
```
### C# Implementation ###
Implicit usage:
```csharp
Microsoft.Xaml.Interactivity.Interaction.GetBehaviors(MyListView).Add(new FadeHeaderBehavior());
```
Explicit usage:
```csharp
Microsoft.Xaml.Interactivity.Interaction.GetBehaviors(MyListView).Add(new FadeHeaderBehavior { HeaderElement = MyHeaderGrid });
```
## Example ##
```xml
<ListView x:Name="MyListView">
<ListView>
<interactivity:Interaction.Behaviors>
<behaviors:FadeHeaderBehavior />
</interactivity:Interaction.Behaviors>
<ListView.Header>
<Grid x:Name="MyHeaderGrid"
MinHeight="250"
Background="{StaticResource Brush-Blue-01}">
<StackPanel VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="20,0">
<TextBlock Text="This Is The Header"
TextAlignment="Center"
FontWeight="Bold"
Style="{ThemeResource TitleTextBlockStyle}"
Foreground="{StaticResource Brush-White}"
Margin="0,5" />
<TextBlock Text="It starts with 100% opacity but will fade to 0% as you scroll up."
Style="{ThemeResource SubtitleTextBlockStyle}"
Foreground="{StaticResource Brush-White}"
VerticalAlignment="Center"
TextAlignment="Center" />
</StackPanel>
<!-- Header Content -->
</ListView.Header>
</ListView>
```
***Explicit usage***: Set the ElementName property using the UIElement of the Header manually
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<ListView>
<interactivity:Interaction.Behaviors>
<behaviors:FadeHeaderBehavior HeaderElement="{Binding ElementName=MyHeaderGrid}" />
</interactivity:Interaction.Behaviors>
<ListView.Header>
<Grid Name="MyHeaderGrid">
<!-- Header Content -->
</Grid>
</ListView.Header>
</ListView>
```
**C#**
[FadeHeader Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader)
***Implicit usage***:
```csharp
Microsoft.Xaml.Interactivity.Interaction.GetBehaviors(MyListView).Add(new FadeHeaderBehavior());
```
## Example Image
***Explicit usage***:
```csharp
Microsoft.Xaml.Interactivity.Interaction.GetBehaviors(MyListView).Add(new FadeHeaderBehavior { HeaderElement = MyHeaderGrid });
```
![FadeHeader Behavior animation](../resources/images/Animations-FadeHeader.gif "FadeHeader Behavior")
## Sample Output
## Requirements (Windows 10 Device Family)
![FadeHeader Behavior animation](../resources/images/Animations/FadeHeader/Sample-Output.gif)
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
## Sample Project
[FadeHeader Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/FadeHeader). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ).
## Requirements
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API

Просмотреть файл

@ -8,65 +8,69 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, light, light anim
# Light
The **Light animation behavior** performs a point light (A point source of light that emits light in all directions) in the middle of a given UIElement.
The light behavior is great drawing the user's eye towards a particular pieces of user interface. You set the distance property of the
light to determine how bright the light will be. The closer the light source, the more focused it will be, but, will make the overall UI element darker.
The further away from the light source the more the light will spread over the UIElement.
**NOTE**: Heavy usage of effects may have a negative impact on the performance of your application.
The Light animation behavior performs a point light (A point source of light that emits light in all directions) in the middle of a given UIElement. You set the distance property of the light to determine how bright the light will be. The closer the light source, the darker the UI element will be. ***NOTE**: Heavy usage of effects may have a negative impact on the performance of your application.*
## Syntax
You can either use the light behavior from your XAML code:
**XAML**
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<interactivity:Interaction.Behaviors>
<interactivity:Interaction.Behaviors>
<behaviors:Light x:Name="LightBehavior"
Distance="10"
Duration="500"
Delay="0"
AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
</interactivity:Interaction.Behaviors>
```
or directly from code:
**C#**
```csharp
var animation = ToolkitLogo.Light(value: 10, duration: 500, delay: 0);
await animation.StartAsync();
MyUIElement.Light(distance: 5, duration: 2500, delay: 250).Start();
await MyUIElement.Light(distance: 5, duration: 2500, delay: 250).StartAsync(); //Light animation can be awaited
```
Behavior animations can also be chained and awaited.
## Sample Output
```csharp
![Light Behavior animation](../resources/images/Animations/Light/Sample-Output.gif)
Element.Rotate(value: 30f, duration: 0.3).StartAsync();
## Properties
await Element.Rotate(value: 30f, duration: 0.3).StartAsync();
var anim = element.Rotate(30f).Fade(0.5).Light(10);
anim.SetDurationForAll(2);
## Examples
- The light behavior is great at drawing the user's eye towards a particular pieces of user interface. Closer the light source, the more focused it will be, but, will make the overall UI element darker. The further away from the light source the more the light will spread over the UIElement.
- Use this to create chaining animations with other animations. Visit the [AnimationSet](\AnimationSet.md) documentation for more information.
**Sample Code**
```csharp
var anim = MyUIElement.Light(5).Offset(offsetX: 100, offsetY: 100).Saturation(0.5).Scale(scaleX: 2, scaleY: 2);
anim.SetDurationForAll(2500);
anim.SetDelay(250);
anim.Completed += animation_completed;
anim.StartAsync();
anim.Start();
```
**Sample Output**
anim.Stop();
![Use Case 1 Output](../resources/images/Animations/Chaining-Animations-Light-Offset-Saturation-Scale.gif)
```
## Sample Project
[Light Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light)
[Light Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Light). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ)
## Example Image
## Requirements
![Light Behavior animation](../resources/images/Animations-Light.gif "Light Behavior")
## Requirements (Windows 10 Device Family)
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, [Windows 10 Anniversary SDK 14393](https://blogs.windows.com/windowsexperience/2016/07/18/build14393/) 10.0.14393.0 |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API

Просмотреть файл

@ -8,98 +8,108 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, offset animation
# Offset
The **Offset animation behavior** gets the number of pixels, from the origin of the associated control, then offsets the control.
The Offset animation is used to move the control from one place to another. Offset animation is applied to all the XAML elements in its parent control/panel. Offset animation doesn't affect the functionality of the control.
## Syntax
**XAML**
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<behaviors:Offset x:Name="OffsetBehavior"
OffsetX="25.0"
OffsetY="25.0"
Duration="500"
Delay="250"
AutomaticallyStart="True"/>
</behaviors:Offset>
<interactivity:Interaction.Behaviors>
<behaviors:Offset x:Name="OffsetBehavior"
OffsetX="25.0"
OffsetY="25.0"
Duration="2500"
Delay="250"
AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
```
or directly from code:
**C#**
```csharp
MyRectangle.Offset(
offsetX: (float)OffsetX,
offsetY: (float)OffsetY
duration: Duration,
delay: Delay);
MyUIElement.Offset(offsetX: 25, offsetY: 25, duration: 2500, delay: 250, easingType: EasingType.Default).Start();
await MyUIElement.Offset(offsetX: 25, offsetY: 25, duration: 2500, delay: 250, easingType: EasingType.Default).StartAsync(); //Offset animation can be awaited
```
## Sample Output
![Offset Behavior animation](../resources/images/Animations/Offset/Sample-Output.gif)
## Properties
| Property Name | Type | Description |
| --- | --- | --- |
| OffsetX | float | The number of pixels to move along the x axis |
| OffsetY | float | The number of pixels to move along the y axis |
| Duration | double | The number of milliseconds the animation should run for |
| Delay | double | The number of milliseconds before the animation is started |
## Chaining animations
### EasingType
Behavior animations can also be chained and awaited.
You can change the way how the animation interpolates between keyframes by defining the EasingType.
```csharp
| EasingType | Explanation | Graphical Explanation |
| ---------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| Default | Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic | |
| Linear | Creates an animation that accelerates or decelerates linear | |
| Back | Retracts the motion of an animation slightly before it begins to animate in the path indicated | ![BackEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/backease-graph.png) |
| Bounce | Creates a bouncing effect | ![BounceEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/bounceease-graph.png) |
| Circle | Creates an animation that accelerates or decelerates using a circular function | ![CircleEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/circleease-graph.png) |
| Cubic | Creates an animation that accelerates or decelerates using the formula f(t) = t3 | ![CubicEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/cubicease-graph.png) |
| Elastic | Creates an animation that resembles a spring oscillating back and forth until it comes to rest | ![ElasticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/elasticease-graph.png) |
| Quadratic | Creates an animation that accelerates or decelerates using the formula f(t) = t2 | ![QuadraticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quadraticease-graph.png) |
| Quartic | Creates an animation that accelerates or decelerates using the formula f(t) = t4 | ![QuarticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quarticease-graph.png) |
| Quintic | Create an animation that accelerates or decelerates using the formula f(t) = t5 | ![QuinticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quinticease-graph.png) |
| Sine | Creates an animation that accelerates or decelerates using a sine formula | ![SineEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/sineease-graph.png) |
Element.Rotate(value: 30f, duration: 0.3).StartAsync();
***Note:** EasingType is used only when AnimationSet.UseComposition == false*
await Element.Rotate(value: 30f, duration: 0.3).StartAsync();
## Examples
var anim = element.Rotate(30f).Fade(0.5).Blur(5);
anim.SetDurationForAll(2);
- You can just call `Offset()` set the control in the orginal position
**Sample Code**
```csharp
await MyUIElement.Offset().Start();
```
- Use await to create a continous movement
**Sample Code**
```csharp
public async void OffsetAsync()
{
await MyUIElement.Offset(offsetX: 100, duration:1000).StartAsync();
await MyUIElement.Offset(offsetX: 100, offsetY: 100, duration: 1000).StartAsync();
await MyUIElement.Offset(offsetX: 0, offsetY:100, duration: 1000).StartAsync();
await MyUIElement.Offset(duration: 1000).StartAsync();
}
```
**Sample Output**
![Use Case 2 Output](../resources/images/Animations/Offset/Use-Case-1.gif)
- Use this to create chaining animations with other animations. Visit the [AnimationSet](\AnimationSet.md) documentation for more information.
**Sample Code**
```csharp
var anim = MyUIElement.Light(5).Offset(offsetX: 100, offsetY: 100).Saturation(0.5).Scale(scaleX: 2, scaleY: 2);
anim.SetDurationForAll(2500);
anim.SetDelay(250);
anim.Completed += animation_completed;
anim.StartAsync();
anim.Start();
```
**Sample Output**
anim.Stop();
![Use Case 2 Output](../resources/images/Animations/Chaining-Animations-Light-Offset-Saturation-Scale.gif)
```
## Sample Project
[Offset Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset)
[Offset Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Offset). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ).
## EasingType
## Requirements
You can change the way how the animation interpolates between keyframes by defining the EasingType using an optional parameter.
| EasingType | Explanation|
| --- | --- |
| Default | Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic. |
| Linear | Creates an animation that accelerates or decelerates linear. |
| Cubic | Creates an animation that accelerates or decelerates using the formula f(t) = t3. |
| Back | Retracts the motion of an animation slightly before it begins to animate in the path indicated. |
| Bounce | Creates a bouncing effect. |
| Elastic | Creates an animation that resembles a spring oscillating back and forth until it comes to rest.|
| Circle | Creates an animation that accelerates or decelerates using a circular function. |
| Quadratic | Creates an animation that accelerates or decelerates using the formula f(t) = t2. |
| Quartic | Creates an animation that accelerates or decelerates using the formula f(t) = t4. |
| Quintic | Create an animation that accelerates or decelerates using the formula f(t) = t5. |
| Sine | Creates an animation that accelerates or decelerates using a sine formula. |
**Example Usage:**
```csharp
MyRectangle.Offset(offsetX: 10, offsetY: 10, duration: 10, delay: 0, easingType: EasingType.Bounce);
```
*Please note that EasingType is used only when AnimationSet.UseComposition == false*
## Example Image
![Offset Behavior animation](../resources/images/Animations-Offset.gif "Offset Behavior")
## Requirements (Windows 10 Device Family)
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API

Просмотреть файл

@ -8,30 +8,44 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, parallaxservice
# ParallaxService
The **ParallaxService** class allows to create a parallax effect for items contained within an element that scrolls like a ScrollViewer or ListView.
The ParallaxService class allows to create a parallax effect for items contained within an element that scrolls like a ScrollViewer or ListView.
## Syntax
**XAML**
```xml
<Image Source="ms-appx:///Assets/Photos/BigFourSummerHeat.png"
ParallaxService.VerticalMultiplier="2.5/>
<Page ...
xmlns:animations="using:Microsoft.Toolkit.Uwp.UI.Animations"/>
<ScrollViewer>
<Image Source="ms-appx:///Assets/Image.png"
animations:ParallaxService.VerticalMultiplier="0.5"
animations:ParallaxService.HorizontalMultiplier="0.5"/>
<!-- Other Controls -->
</ScrollViewer>
```
You can define horizontal or vertical multiplier to determine the speed ratio that you want to apply to your element.
**C#**
[ParallaxService Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ParallaxService)
```csharp
MyUIElement.SetValue(ParallaxService.VerticalMultiplierProperty, 0.5);
MyUIElement.SetValue(ParallaxService.HorizontalMultiplierProperty, 0.5);
```
## Example Image
## Sample Output
![ParallaxService](../resources/images/ParallaxService.gif "ParallaxService")
![ParallaxService](../resources/images/Animations/ParallaxService/Sample-Output.gif)
## Requirements (Windows 10 Device Family)
## Sample Project
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
[ParallaxService Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ParallaxService). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ)
## Requirements
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API

Просмотреть файл

@ -8,29 +8,38 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, ReorderGridAnimat
# ReorderGridAnimation
The **ReorderGridAnimation** class allows your GridView controls to animate items into position when the size of the GridView changes.
The ReorderGridAnimation class allows your GridView controls to animate items into position when the size of the GridView changes.
## Syntax
**XAML**
```xml
<GridView x:Name="GridItems"
<Page ...
xmlns:animations="using:Microsoft.Toolkit.Uwp.UI.Animations"/>
<GridView x:Name="MyGridView"
animations:ReorderGridAnimation.Duration="250"/>
```
[ReorderGridAnimation Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ReorderGridAnimation)
**C#**
## Example Image
```csharp
MyGridView.SetValue(ReorderGridAnimation.DurationProperty, 250);
```
## Sample Output
![ReorderGridAnimation](../resources/images/ReorderGrid.gif "ReorderGridAnimation")
![ReorderGridAnimation](../resources/images/Animations/ReorderGridAnimation/Sample-Output.gif)
## Requirements (Windows 10 Device Family)
## Sample Project
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
[ReorderGridAnimation Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ReorderGridAnimation). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ)
## Requirements
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API
* [ReorderGridAnimation source code](https://github.com/Microsoft/UWPCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI.Animations/ReorderGridAnimation.cs)

Просмотреть файл

@ -8,13 +8,19 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, rotate, rotate an
# Rotate
The **Rotate animation behavior** allows users to modify and animate the control's rotation. Parameters include: angle values, time, pause delay, duration, and diameter.
The Rotate animation allows users to modify and animate the control's rotation. Rotate animation is applied to all the XAML elements in its parent control/panel. Rotate animation doesn't affect the functionality of the control.
## Syntax
```xml
**XAML**
<behaviors:Rotate x:Name="RotateBehavior"
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<interactivity:Interaction.Behaviors>
<behaviors:Rotate x:Name="RotateBehavior"
Value="180"
CenterX="0.0"
CenterY="0.0"
@ -22,89 +28,71 @@ The **Rotate animation behavior** allows users to modify and animate the control
Delay="250"
AutomaticallyStart="True"/>
</behaviors:Rotate>
</interactivity:Interaction.Behaviors>
```
or directly from code:
**C#**
```csharp
MyRectangle.Rotate(
value: (float)Value,
centerX: (float)CenterX,
centerY: (float)CenterY,
duration: Duration,
delay: Delay);
MyUIElement.Rotate(value: 0.5f, centerX: 0.0f, centerY: 0.0f, duration: 2500, delay: 250, easingType: EasingType.Default).Start();
await MyUIElement.Rotate(value: 0.5f, centerX: 0.0f, centerY: 0.0f, duration: 2500, delay: 250, easingType: EasingType.Default).StartAsync(); //Rotate animation can be awaited
```
## Sample Output
![Rotate Behavior animation](../resources/images/Animations/Rotate/Sample-Output.gif)
## Properties
| Property Name | Type | Description |
| --- | --- | --- |
| Value | float | The rotation of the element in degrees |
| CenterX | float | The pivot point on the x axis |
| CenterY | float | The pivot point on the y axis |
| Duration | double | The number of milliseconds the animation should run for |
| Delay | double | The number of milliseconds before the animation is started |
## Chaining animations
Behavior animations can also be chained and awaited.
```csharp
Element.Rotate(value: 30f, duration: 0.3).StartAsync();
await Element.Rotate(value: 30f, duration: 0.3).StartAsync();
var anim = element.Rotate(30f).Fade(0.5).Blur(5);
anim.SetDurationForAll(2);
anim.Completed += animation_completed;
anim.StartAsync();
anim.Stop();
```
[Rotate Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate)
## EasingType
### EasingType
You can change the way how the animation interpolates between keyframes by defining the EasingType using an optional parameter.
| EasingType | Explanation|
| --- | --- |
| Default | Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic. |
| Linear | Creates an animation that accelerates or decelerates linear. |
| Cubic | Creates an animation that accelerates or decelerates using the formula f(t) = t3. |
| Back | Retracts the motion of an animation slightly before it begins to animate in the path indicated. |
| Bounce | Creates a bouncing effect. |
| Elastic | Creates an animation that resembles a spring oscillating back and forth until it comes to rest.|
| Circle | Creates an animation that accelerates or decelerates using a circular function. |
| Quadratic | Creates an animation that accelerates or decelerates using the formula f(t) = t2. |
| Quartic | Creates an animation that accelerates or decelerates using the formula f(t) = t4. |
| Quintic | Create an animation that accelerates or decelerates using the formula f(t) = t5. |
| Sine | Creates an animation that accelerates or decelerates using a sine formula. |
| EasingType | Explanation | Graphical Explanation |
| ---------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| Default | Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic | |
| Linear | Creates an animation that accelerates or decelerates linear | |
| Back | Retracts the motion of an animation slightly before it begins to animate in the path indicated | ![BackEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/backease-graph.png) |
| Bounce | Creates a bouncing effect | ![BounceEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/bounceease-graph.png) |
| Circle | Creates an animation that accelerates or decelerates using a circular function | ![CircleEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/circleease-graph.png) |
| Cubic | Creates an animation that accelerates or decelerates using the formula f(t) = t3 | ![CubicEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/cubicease-graph.png) |
| Elastic | Creates an animation that resembles a spring oscillating back and forth until it comes to rest | ![ElasticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/elasticease-graph.png) |
| Quadratic | Creates an animation that accelerates or decelerates using the formula f(t) = t2 | ![QuadraticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quadraticease-graph.png) |
| Quartic | Creates an animation that accelerates or decelerates using the formula f(t) = t4 | ![QuarticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quarticease-graph.png) |
| Quintic | Create an animation that accelerates or decelerates using the formula f(t) = t5 | ![QuinticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quinticease-graph.png) |
| Sine | Creates an animation that accelerates or decelerates using a sine formula | ![SineEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/sineease-graph.png) |
**Example Usage:**
```csharp
MyRectangle.Offset(value: 10, duration: 10, delay: 0, easingType: EasingType.Bounce);
```
***Note:** EasingType is used only when AnimationSet.UseComposition == false*
*Please note that EasingType is used only when AnimationSet.UseComposition == false*
## Examples
## Example Image
- Use this to create chaining animations with other animations. Visit the [AnimationSet](\AnimationSet.md) documentation for more information.
![Rotate Behavior animation](../resources/images/Animations-Rotate.gif "Rotate Behavior")
**Sample Code**
```csharp
var anim = MyUIElement.Rotate(30).Fade(0.5f).Blur(5);
anim.SetDurationForAll(2500);
anim.SetDelay(250);
anim.Completed += animation_completed;
anim.Start();
```
**Sample Output**
## Requirements (Windows 10 Device Family)
![Use Case 1 Output](../resources/images/Animations/Chaining-Animations-Blur-Fade-Rotate.gif)
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
## Sample Project
[Rotate Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Rotate). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ).
## Requirements
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API
* [Rotate source code](https://github.com/Microsoft/UWPCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/Rotate.cs)

Просмотреть файл

@ -8,74 +8,84 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, saturation animat
# Saturation
The **Saturation animation behavior** selectively saturates a XAML element.
Sometimes you want an element to desaturate, a common example of this could be when you mouse over a UI Element, now you can apply a SaturationBehavior to the original element at run time.
**NOTE**: This animation REQUIRES the [Windows 10 Anniversary SDK 14393](https://blogs.windows.com/windowsexperience/2016/07/18/build14393/) 10.0.14393.0 in order for it to work.
The Saturation animation selectively saturates a XAML element. Saturation animation is applied to all the XAML elements in its parent control/panel. Saturation animation doesn't affect the functionality of the control.
## Syntax
You can either use the saturation behavior from your XAML code:
**XAML**
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<interactivity:Interaction.Behaviors>
<interactivity:Interaction.Behaviors>
<behaviors:Saturation x:Name="SaturationBehavior"
Value="10"
Duration="500"
Value="0"
Duration="2500"
Delay="250"
AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
</interactivity:Interaction.Behaviors>
```
or directly from code:
**C#**
```csharp
ToolkitLogo.Saturation(value: 10, duration: 500, delay: 250);
ToolkitLogo.Saturation(value: 0, duration: 500, delay: 250);
```
## Sample Output
![Saturation Behavior animation](../resources/images/Animations/Saturation/Sample-Output.gif)
## Properties
| Property Name | Type | Description |
| --- | --- | --- |
| Value | double | A range between 0 and 1 on how to saturate the UI Element. 1 is maximum saturation, 0 is desaturated. |
| Duration | double | The number of milliseconds the animation should run for |
| Delay | double | The number of milliseconds before the animation is started |
## Chaining animations
Behavior animations can also be chained and awaited.
## Examples
```csharp
- Sometimes you want an element to desaturate, a common example of this could be when you mouse over a UI Element, now you can apply a SaturationBehavior to the original element at run time.
Element.Rotate(value: 30f, duration: 0.3).StartAsync();
**Sample Code**
```csharp
private void MyUIElement_PointerEntered(object sender, PointerRoutedEventArgs e)
{
MyUIElement.Saturation(value: 1).Start();
}
await Element.Rotate(value: 30f, duration: 0.3).StartAsync();
private void MyUIElement_PointerExited(object sender, PointerRoutedEventArgs e)
{
MyUIElement.Saturation(value: 0).Start();
}
```
**Sample Output**
var anim = element.Rotate(30f).Fade(0.5).Blur(5);
anim.SetDurationForAll(2);
![Use Case 1 Output](../resources/images/Animations/Saturation/Use-Case-1.gif)
- Use this to create chaining animations with other animations. Visit the [AnimationSet](\AnimationSet.md) documentation for more information.
**Sample Code**
```csharp
var anim = MyUIElement.Light(5).Offset(offsetX: 100, offsetY: 100).Saturation(0.5).Scale(scaleX: 2, scaleY: 2);
anim.SetDurationForAll(2500);
anim.SetDelay(250);
anim.Completed += animation_completed;
anim.StartAsync();
anim.Start();
```
**Sample Output**
anim.Stop();
![Use Case 2 Output](../resources/images/Animations/Chaining-Animations-Light-Offset-Saturation-Scale.gif)
```
## Sample Project
[Saturation Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation)
[Saturation Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Saturation). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ).
## Example Image
## Requirements
![Saturation Behavior animation](../resources/images/Animations-Saturation.gif "Saturation Behavior")
## Requirements (Windows 10 Device Family)
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, [Windows 10 Anniversary SDK 14393](https://blogs.windows.com/windowsexperience/2016/07/18/build14393/) 10.0.14393.0 |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API

Просмотреть файл

@ -8,11 +8,16 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, scale animation,
# Scale
The **Scale animation behavior** allows you to change a control's scale by increasing or decreasing the control through animation. For example, perhaps you want an entry field to change size when the user taps it.
The Scale animation allows you to change a control's scale by increasing or decreasing the control through animation. Scale animation is applied to all the XAML elements in its parent control/panel. Scale animation doesn't affect the functionality of the control.
## Syntax
**XAML**
```xml
<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"/>
<interactivity:Interaction.Behaviors>
<behaviors:Scale x:Name="Scale"
@ -24,89 +29,88 @@ The **Scale animation behavior** allows you to change a control's scale by incre
Delay="500"
AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
```
or directly from code:
**C#**
```csharp
MyRectangle.Scale(
scaleX: (float)ScaleX,
scaleY: (float)ScaleY,
centerX: (float)CenterX,
centerY: (float)CenterY,
duration: Duration,
delay: Delay);
MyUIElement.Scale(scaleX: 2, scaleY: 2, centerX: 0, centerY: 0, duration: 2500, delay: 250, easingType: EasingType.Default).Start();
```
## Sample Output
![Scale Behavior animation](../resources/images/Animations/Fade/Sample-Output.gif)
## Properties
| Property Name | Type | Description |
| --- | --- | --- |
| ScaleX | float | The scale of the element along the x axis |
| ScaleY | float | The scale of the element along the y axis |
| CenterX | float | The pivot point on the x axis |
| CenterY | float | The pivot point on the y axis |
| Duration | double | The number of milliseconds the animation should run for |
| Delay | double | The number of milliseconds before the animation is started |
## Chaining animations
Behaviors can also be chained and awaited.
### EasingType
```csharp
You can change the way how the animation interpolates between keyframes by defining the EasingType.
Element.Rotate(value: 30f, duration: 0.3).StartAsync();
| EasingType | Explanation | Graphical Explanation |
| ---------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| Default | Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic | |
| Linear | Creates an animation that accelerates or decelerates linear | |
| Back | Retracts the motion of an animation slightly before it begins to animate in the path indicated | ![BackEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/backease-graph.png) |
| Bounce | Creates a bouncing effect | ![BounceEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/bounceease-graph.png) |
| Circle | Creates an animation that accelerates or decelerates using a circular function | ![CircleEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/circleease-graph.png) |
| Cubic | Creates an animation that accelerates or decelerates using the formula f(t) = t3 | ![CubicEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/cubicease-graph.png) |
| Elastic | Creates an animation that resembles a spring oscillating back and forth until it comes to rest | ![ElasticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/elasticease-graph.png) |
| Quadratic | Creates an animation that accelerates or decelerates using the formula f(t) = t2 | ![QuadraticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quadraticease-graph.png) |
| Quartic | Creates an animation that accelerates or decelerates using the formula f(t) = t4 | ![QuarticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quarticease-graph.png) |
| Quintic | Create an animation that accelerates or decelerates using the formula f(t) = t5 | ![QuinticEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/quinticease-graph.png) |
| Sine | Creates an animation that accelerates or decelerates using a sine formula | ![SineEase](https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/media/sineease-graph.png) |
await Element.Rotate(value: 30f, duration: 0.3).StartAsync();
***Note:** EasingType is used only when AnimationSet.UseComposition == false*
var anim = element.Rotate(30f).Fade(0.5).Blur(5);
anim.SetDurationForAll(2);
## Examples
- Use this to create popup effect
**Sample Code**
```csharp
UIElement lastTapped = null;
private void MyUIElement_Tapped(object sender, TappedRoutedEventArgs e)
{
if (lastTapped != null)
{
lastTapped.Scale(centerX: 50, centerY: 50).Start();
Canvas.SetZIndex(lastTapped, 0);
}
lastTapped = sender as UIElement;
Canvas.SetZIndex(lastTapped, 1);
lastTapped.Scale(scaleX: 2, scaleY: 2, centerX: 50, centerY: 50).Start();
}
```
**Sample Output**
![Use Case 1 Output](../resources/images/Animations/Saturation/Scale.gif)
- Use this to create chaining animations with other animations. Visit the [AnimationSet](\AnimationSet.md) documentation for more information.
**Sample Code**
```csharp
var anim = MyUIElement.Light(5).Offset(offsetX: 100, offsetY: 100).Saturation(0.5).Scale(scaleX: 2, scaleY: 2);
anim.SetDurationForAll(2500);
anim.SetDelay(250);
anim.Completed += animation_completed;
anim.StartAsync();
anim.Start();
```
**Sample Output**
anim.Stop();
![Use Case 2 Output](../resources/images/Animations/Chaining-Animations-Light-Offset-Saturation-Scale.gif)
```
## Sample Project
[Scale Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale)
[Scale Behavior Sample Page Source](https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Scale). You can see this in action in [UWP Community Toolkit Sample App](https://www.microsoft.com/store/apps/9NBLGGH4TLCQ).
## EasingType
## Requirements
You can change the way how the animation interpolates between keyframes by defining the EasingType using an optional parameter.
| EasingType | Explanation|
| --- | --- |
| Default | Creates an animation that accelerates with the default EasingType which is specified in AnimationExtensions.DefaultEasingType which is by default Cubic. |
| Linear | Creates an animation that accelerates or decelerates linear. |
| Cubic | Creates an animation that accelerates or decelerates using the formula f(t) = t3. |
| Back | Retracts the motion of an animation slightly before it begins to animate in the path indicated. |
| Bounce | Creates a bouncing effect. |
| Elastic | Creates an animation that resembles a spring oscillating back and forth until it comes to rest.|
| Circle | Creates an animation that accelerates or decelerates using a circular function. |
| Quadratic | Creates an animation that accelerates or decelerates using the formula f(t) = t2. |
| Quartic | Creates an animation that accelerates or decelerates using the formula f(t) = t4. |
| Quintic | Create an animation that accelerates or decelerates using the formula f(t) = t5. |
| Sine | Creates an animation that accelerates or decelerates using a sine formula. |
**Example Usage:**
```csharp
MyRectangle.Offset(value: 10, duration: 10, delay: 0, easingType: EasingType.Bounce);
```
*Please note that EasingType is used only when AnimationSet.UseComposition == false*
## Example Image
![Scale Behavior animation](../resources/images/Animations-Scale.gif "Scale Behavior")
## Requirements (Windows 10 Device Family)
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| --- | --- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| [Device family](http://go.microsoft.com/fwlink/p/?LinkID=526370) | Universal, 10.0.14393.0 or higher |
| ---------------------------------------------------------------- | ----------------------------------- |
| Namespace | Microsoft.Toolkit.Uwp.UI.Animations |
| NuGet package | [Microsoft.Toolkit.Uwp.UI.Animations](https://www.nuget.org/packages/Microsoft.Toolkit.Uwp.UI.Animations/) |
## API

Просмотреть файл

@ -19,7 +19,7 @@ The **ApplicationViewExtensions, StatusBarExtensions & TitleBarExtensions** prov
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.Toolkit.Uwp.SampleApp.SamplePages"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewHelper="using:Microsoft.Toolkit.Uwp.UI.Extensions"
xmlns:extensions="using:Microsoft.Toolkit.Uwp.UI.Extensions"
extensions:ApplicationViewExtensions.Title="View Extensions"
extensions:StatusBarExtensions.BackgroundColor="Blue"
extensions:StatusBarExtensions.BackgroundOpacity="0.8"

Двоичные данные
docs/resources/images/Animations/AnimationSet/Use-Case-1.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 MiB

Двоичные данные
docs/resources/images/Animations/AnimationSet/Use-Case-2.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.1 MiB

Двоичные данные
docs/resources/images/Animations/Blur/Sample-Output.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 265 KiB

Двоичные данные
docs/resources/images/Animations/Blur/Use-Case-1.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.1 MiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 114 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 957 KiB

Двоичные данные
docs/resources/images/Animations/Fade/Sample-Output.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 34 KiB

Двоичные данные
docs/resources/images/Animations/FadeHeader/Sample-Output.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 966 KiB

Двоичные данные
docs/resources/images/Animations/Light/Sample-Output.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 132 KiB

Двоичные данные
docs/resources/images/Animations/Offset/Sample-Output.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 93 KiB

Двоичные данные
docs/resources/images/Animations/Offset/Use-Case-1.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 121 KiB

Двоичные данные
docs/resources/images/Animations/ParallaxService/Sample-Output.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 MiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 27 MiB

Двоичные данные
docs/resources/images/Animations/Rotate/Sample-Output.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 285 KiB

Двоичные данные
docs/resources/images/Animations/Saturation/Sample-Output.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.4 MiB

Двоичные данные
docs/resources/images/Animations/Saturation/Use-Case-1.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 132 KiB

Двоичные данные
docs/resources/images/Animations/Scale/Sample-Output.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 176 KiB

Двоичные данные
docs/resources/images/Animations/Scale/Use-Case-1.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 MiB

Просмотреть файл

@ -12,7 +12,7 @@ The UWP Community Toolkit is a collection of helper functions, custom controls,
## Getting started
Please read the [getting Started with the UWP Toolkit](http://uwpcommunitytoolkit.readthedocs.io/en/master/Getting-Started/) page for more detailed information about using the toolkit.
Please read the [getting Started with the UWP Toolkit](http://uwpcommunitytoolkit.com/en/master/Getting-Started/) page for more detailed information about using the toolkit.
## UWP Community Toolkit Sample App
@ -40,6 +40,10 @@ Once you search you should see a list similar to the one below (versions may be
| Microsoft.Toolkit.Uwp.Connectivity | API helpers such as BluetoothLEHelper and Networking |
| Microsoft.Toolkit.Uwp.DeveloperTools | XAML user controls and services to help developer building their app |
## <a name="supported"></a> Supported SDKs
* Anniversary Update (14393)
* Creators Update (15063)
## Features
### Animations
@ -135,8 +139,9 @@ Once you search you should see a list similar to the one below (versions may be
## Feedback and Requests
Please use [GitHub issues](https://github.com/Microsoft/UWPCommunityToolkit/issues) for questions and comments.
For feature requests, please create en entry in our [Uservoice](https://wpdev.uservoice.com/forums/110705-universal-windows-platform/category/193402-uwp-community-toolkit).
Please use [GitHub issues](https://github.com/Microsoft/UWPCommunityToolkit/issues) for bug reports and feature requests.
For feature requests, please also create en entry in our [Uservoice](https://wpdev.uservoice.com/forums/110705-universal-windows-platform/category/193402-uwp-community-toolkit).
For general questions and support, please use [Stack Overflow](https://stackoverflow.com/search?q=uwp+community+toolkit) where questions should be tagged with the tag `uwp-community-toolkit`
## Contributing
Do you want to contribute? Here are our [contribution guidelines](https://github.com/Microsoft/UWPCommunityToolkit/blob/master/contributing.md).