Merge branch 'master' into unsetValue-to-null

This commit is contained in:
Michael Hawker MSFT (XAML Llama) 2021-05-03 10:52:27 -07:00 коммит произвёл GitHub
Родитель b2e9725491 2b124ff5e7
Коммит 89fe685a98
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 355 добавлений и 17 удалений

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

@ -499,7 +499,7 @@ namespace Microsoft.Toolkit.Uwp.Notifications
GetAdaptiveTileContent(MediumTile).Children.Add(child);
}
if (size.HasFlag(TileSize.Wide) && WideTile != null && GetAdaptiveTileContent(MediumTile) != null)
if (size.HasFlag(TileSize.Wide) && WideTile != null && GetAdaptiveTileContent(WideTile) != null)
{
GetAdaptiveTileContent(WideTile).Children.Add(child);
}

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

@ -5,15 +5,49 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors"
mc:Ignorable="d">
<Grid>
<StackPanel Spacing="120" VerticalAlignment="Center">
<!--This is a static element, with some Visual properties being modified through
the VisualExtensions class. You can modify their values to see how the position,
orientation and alignment of the Border element changes.-->
<Border Height="100"
Width="100"
Background="Purple"
ui:VisualExtensions.CenterPoint="50,50,0"
ui:VisualExtensions.Offset="50"
ui:VisualExtensions.Opacity="0.5"
ui:VisualExtensions.RotationAngleInDegrees="80"
ui:VisualExtensions.Scale="2, 0.5, 1"
ui:VisualExtensions.NormalizedCenterPoint="0.5" />
</Grid>
ui:VisualExtensions.NormalizedCenterPoint="0.5"
ui:VisualExtensions.Translation="20,12,0"/>
<!--This Button demonstrates the VisualExtensions.Translation property in combination with a translation
animation. The Translation property is set to indicate the starting position of the element (relative
to its offset), and the animation will modify that to reach the specified translation value. Note how
the animation doesn't have an explicit starting value, as it will just start animating the translation
from the current value set via the VisualExtensions.Translation attached property.-->
<Button Height="120"
Width="360"
Background="Green"
Content="Click me!"
FontSize="32"
ui:VisualExtensions.Translation="20,-40,0">
<ani:Explicit.Animations>
<ani:AnimationSet x:Name="MoveAnimation">
<ani:TranslationAnimation To="480,80,0" Duration="0:0:2"/>
</ani:AnimationSet>
</ani:Explicit.Animations>
<interactivity:Interaction.Behaviors>
<interactions:EventTriggerBehavior EventName="Click">
<behaviors:StartAnimationAction Animation="{Binding ElementName=MoveAnimation}"/>
</interactions:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</Button>
</StackPanel>
</Page>

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

@ -3,11 +3,15 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<StackPanel Spacing="120" VerticalAlignment="Center">
<Border Height="100"
Width="100"
Background="Purple"
@ -16,6 +20,25 @@
ui:VisualExtensions.Opacity="0.5"
ui:VisualExtensions.RotationAngleInDegrees="80"
ui:VisualExtensions.Scale="2, 0.5, 1"
ui:VisualExtensions.NormalizedCenterPoint="0.5"/>
</Grid>
ui:VisualExtensions.NormalizedCenterPoint="0.5"
ui:VisualExtensions.Translation="20,12,0"/>
<Button
Height="120"
Width="360"
Background="Green"
Content="Click me!"
FontSize="32"
ui:VisualExtensions.Translation="20,-40,0">
<ani:Explicit.Animations>
<ani:AnimationSet x:Name="MoveAnimation">
<ani:TranslationAnimation To="480,80,0" Duration="0:0:2"/>
</ani:AnimationSet>
</ani:Explicit.Animations>
<interactivity:Interaction.Behaviors>
<interactions:EventTriggerBehavior EventName="Click">
<behaviors:StartAnimationAction Animation="{Binding ElementName=MoveAnimation}"/>
</interactions:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</Button>
</StackPanel>
</Page>

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

@ -20,7 +20,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
nameof(CustomPaletteColors),
typeof(ObservableCollection<Windows.UI.Color>),
typeof(ColorPicker),
new PropertyMetadata(Windows.UI.Color.FromArgb(0x00, 0x00, 0x00, 0x00)));
new PropertyMetadata(null));
/// <summary>
/// Gets the list of custom palette colors.
@ -64,7 +64,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
nameof(CustomPalette),
typeof(IColorPalette),
typeof(ColorPicker),
new PropertyMetadata(DependencyProperty.UnsetValue));
new PropertyMetadata(null));
/// <summary>
/// Gets or sets the custom color palette.

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

@ -41,6 +41,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.ColorPickerConverters
}
else
{
// Invalid color value provided
return DependencyProperty.UnsetValue;
}
@ -51,6 +52,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.ColorPickerConverters
}
catch
{
// Invalid parameter provided, unable to convert to integer
return DependencyProperty.UnsetValue;
}
@ -120,7 +122,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.ColorPickerConverters
object parameter,
string language)
{
throw new NotImplementedException();
return DependencyProperty.UnsetValue;
}
}
}

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

@ -35,6 +35,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.ColorPickerConverters
}
else
{
// Invalid color value provided
return DependencyProperty.UnsetValue;
}
@ -59,7 +60,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.ColorPickerConverters
}
catch
{
throw new ArgumentException("Invalid hex color value provided");
// Invalid hex color value provided
return DependencyProperty.UnsetValue;
}
}
else
@ -70,7 +72,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.ColorPickerConverters
}
catch
{
throw new ArgumentException("Invalid hex color value provided");
// Invalid hex color value provided
return DependencyProperty.UnsetValue;
}
}
}

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

@ -41,6 +41,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.ColorPickerConverters
}
else
{
// Invalid color value provided
return DependencyProperty.UnsetValue;
}
@ -82,7 +83,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.ColorPickerConverters
object parameter,
string language)
{
throw new NotImplementedException();
return DependencyProperty.UnsetValue;
}
/// <summary>

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

@ -24,7 +24,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.UI.Xaml" Version="2.5.0" />
<PackageReference Include="System.Text.Json" Version="4.7.2" />
<PackageReference Include="System.Text.Json" Version="5.0.2" />
<PackageReference Include="Win2D.uwp" Version="1.25.0" />
</ItemGroup>

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

@ -34,6 +34,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Converters
}
else
{
// Invalid color value provided
return DependencyProperty.UnsetValue;
}
@ -47,7 +48,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Converters
object parameter,
string language)
{
throw new NotImplementedException();
return DependencyProperty.UnsetValue;
}
}
}

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

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Globalization;
using System.Numerics;
using Windows.UI.Composition;
using Windows.UI.Xaml;
@ -114,6 +115,36 @@ namespace Microsoft.Toolkit.Uwp.UI
obj.SetValue(OffsetProperty, value);
}
/// <summary>
/// Gets the <c>"Translation"</c> property of the underlying <see cref="Visual"/> object for a <see cref="UIElement"/>, in <see cref="string"/> form.
/// </summary>
/// <param name="obj">The <see cref="DependencyObject"/> instance.</param>
/// <returns>The <see cref="string"/> representation of the <c>"Translation"</c> property property.</returns>
public static string GetTranslation(DependencyObject obj)
{
if (!DesignTimeHelpers.IsRunningInLegacyDesignerMode && obj is UIElement element)
{
return GetTranslationForElement(element);
}
return (string)obj.GetValue(TranslationProperty);
}
/// <summary>
/// Sets the <c>"Translation"</c> property of the underlying <see cref="Visual"/> object for a <see cref="UIElement"/>, in <see cref="string"/> form.
/// </summary>
/// <param name="obj">The <see cref="DependencyObject"/> instance.</param>
/// <param name="value">The <see cref="string"/> representation of the <c>"Translation"</c> property property to be set.</param>
public static void SetTranslation(DependencyObject obj, string value)
{
if (!DesignTimeHelpers.IsRunningInLegacyDesignerMode && obj is UIElement element)
{
SetTranslationForElement(value, element);
}
obj.SetValue(TranslationProperty, value);
}
/// <summary>
/// Gets the <see cref="Visual.Opacity"/> of a UIElement
/// </summary>
@ -334,6 +365,12 @@ namespace Microsoft.Toolkit.Uwp.UI
public static readonly DependencyProperty OffsetProperty =
DependencyProperty.RegisterAttached("Offset", typeof(string), typeof(VisualExtensions), new PropertyMetadata(null, OnOffsetChanged));
/// <summary>
/// Identifies the Translation attached property.
/// </summary>
public static readonly DependencyProperty TranslationProperty =
DependencyProperty.RegisterAttached("Translation", typeof(string), typeof(VisualExtensions), new PropertyMetadata(null, OnTranslationChanged));
/// <summary>
/// Identifies the Opacity attached property.
/// </summary>
@ -400,6 +437,14 @@ namespace Microsoft.Toolkit.Uwp.UI
}
}
private static void OnTranslationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is string str)
{
SetTranslation(d, str);
}
}
private static void OnOpacityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is double dbl)
@ -503,6 +548,37 @@ namespace Microsoft.Toolkit.Uwp.UI
visual.Offset = value.ToVector3();
}
private static string GetTranslationForElement(UIElement element)
{
CompositionGetValueStatus result = GetVisual(element).Properties.TryGetVector3("Translation", out Vector3 translation);
return result switch
{
// The ("G", CultureInfo.InvariantCulture) combination produces a string with the default numeric
// formatting style, and using ',' as component separator, so that the resulting text can safely
// be parsed back if needed with the StringExtensions.ToVector3(string) extension, which uses
// the invariant culture mode by default so that the syntax will always match that from XAML.
CompositionGetValueStatus.Succeeded => translation.ToString("G", CultureInfo.InvariantCulture),
_ => "<0, 0, 0>"
};
}
private static void SetTranslationForElement(string value, UIElement element)
{
ElementCompositionPreview.SetIsTranslationEnabled(element, true);
// The "Translation" attached property refers to the "hidden" property that is enabled
// through "ElementCompositionPreview.SetIsTranslationEnabled". The value for this property
// is not available directly on the Visual class and can only be accessed through its property
// set. Note that this "Translation" value is not the same as Visual.TransformMatrix.Translation.
// In fact, the latter doesn't require to be explicitly enabled and is actually combined with
// this at runtime (ie. the whole transform matrix is combined with the additional translation
// from the "Translation" property, if any), and the two can be set and animated independently.
// In this case we're just interested in the "Translation" property, which is more commonly used
// as it can also be animated directly with a Vector3 animation instead of a Matrix4x4 one.
GetVisual(element).Properties.InsertVector3("Translation", value.ToVector3());
}
private static double GetOpacityForElement(UIElement element)
{
var visual = GetVisual(element);

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

@ -0,0 +1,113 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Linq;
using Microsoft.Toolkit.Uwp.Notifications;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests.Notifications
{
#if !WINRT
[TestClass]
public class TestTileContentBuilder
{
[TestMethod]
public void AddTextTest_OnSmallTileOnly()
{
// Arrange
string text = "text on small tile";
TileContentBuilder builder = new TileContentBuilder();
builder.AddTile(TileSize.Small);
// Act
builder.AddText(text);
// Assert
var tileText = GetTileAdaptiveText(builder, TileSize.Small);
Assert.IsNotNull(tileText);
Assert.AreSame("text on small tile", (string)tileText.Text);
}
[TestMethod]
public void AddTextTest_OnMediumTileOnly()
{
// Arrange
string text = "text on medium tile";
TileContentBuilder builder = new TileContentBuilder();
builder.AddTile(TileSize.Medium);
// Act
builder.AddText(text);
// Assert
var tileText = GetTileAdaptiveText(builder, TileSize.Medium);
Assert.IsNotNull(tileText);
Assert.AreSame("text on medium tile", (string)tileText.Text);
}
[TestMethod]
public void AddTextTest_OnWideTileOnly()
{
// Arrange
string text = "text on wide tile";
TileContentBuilder builder = new TileContentBuilder();
builder.AddTile(TileSize.Wide);
// Act
builder.AddText(text);
// Assert
var tileText = GetTileAdaptiveText(builder, TileSize.Wide);
Assert.IsNotNull(tileText);
Assert.AreSame("text on wide tile", (string)tileText.Text);
}
[TestMethod]
public void AddTextTest_OnLargeTileOnly()
{
// Arrange
string text = "text on large tile";
TileContentBuilder builder = new TileContentBuilder();
builder.AddTile(TileSize.Large);
// Act
builder.AddText(text);
// Assert
var tileText = GetTileAdaptiveText(builder, TileSize.Large);
Assert.IsNotNull(tileText);
Assert.AreSame("text on large tile", (string)tileText.Text);
}
private static AdaptiveText GetTileAdaptiveText(TileContentBuilder builder, TileSize size)
{
TileBinding tileBinding;
switch (size)
{
case TileSize.Small:
tileBinding = builder.Content.Visual.TileSmall;
break;
case TileSize.Medium:
tileBinding = builder.Content.Visual.TileMedium;
break;
case TileSize.Wide:
tileBinding = builder.Content.Visual.TileWide;
break;
case TileSize.Large:
tileBinding = builder.Content.Visual.TileLarge;
break;
default:
return null;
}
var content = (TileBindingContentAdaptive)tileBinding.Content;
return content.Children.FirstOrDefault() as AdaptiveText;
}
}
#endif
}

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

@ -11,6 +11,7 @@
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)TestAssertHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TestMail.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TestTileContentBuilder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TestToastArguments.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TestToastContentBuilder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TestWeather.cs" />

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

@ -0,0 +1,83 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Toolkit.Uwp;
using Windows.UI.Xaml.Controls;
using Microsoft.Toolkit.Uwp.UI;
using System.Numerics;
using Windows.UI.Composition;
using Microsoft.Toolkit.Uwp.UI.Animations;
namespace UnitTests.UWP.UI
{
[TestClass]
[TestCategory("Test_VisualExtensions")]
public class Test_VisualExtensions : VisualUITestBase
{
[TestMethod]
public async Task GetDefaultTranslation()
{
await App.DispatcherQueue.EnqueueAsync(() =>
{
var button = new Button();
string text = VisualExtensions.GetTranslation(button);
Assert.AreEqual(text, "<0, 0, 0>");
});
}
[TestMethod]
public async Task SetAndGetTranslation()
{
await App.DispatcherQueue.EnqueueAsync(async () =>
{
var button = new Button();
var grid = new Grid() { Children = { button } };
VisualExtensions.SetTranslation(button, "80, 20, 0");
await SetTestContentAsync(grid);
var success = button.GetVisual().Properties.TryGetVector3("Translation", out Vector3 translation);
Assert.AreEqual(success, CompositionGetValueStatus.Succeeded);
Assert.AreEqual(translation, new Vector3(80, 20, 0));
string text = VisualExtensions.GetTranslation(button);
Assert.AreEqual(text, new Vector3(80, 20, 0).ToString());
});
}
[TestMethod]
public async Task SetAndAnimateTranslation()
{
await App.DispatcherQueue.EnqueueAsync(async () =>
{
var button = new Button();
var grid = new Grid() { Children = { button } };
VisualExtensions.SetTranslation(button, "80, 20, 0");
await SetTestContentAsync(grid);
await AnimationBuilder.Create()
.Translation(to: new Vector3(11, 22, 0))
.StartAsync(button);
var success = button.GetVisual().Properties.TryGetVector3("Translation", out Vector3 translation);
Assert.AreEqual(success, CompositionGetValueStatus.Succeeded);
Assert.AreEqual(translation, new Vector3(11, 22, 0));
string text = VisualExtensions.GetTranslation(button);
Assert.AreEqual(text, new Vector3(11, 22, 0).ToString());
});
}
}
}

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

@ -124,7 +124,7 @@
<!-- DO NOT UPGRADE THIS PACKAGE FROM 10.0.3, this is used for upgrade testing between 6.1.1 and 7.0.0 for the Object Serializers -->
</PackageReference>
<PackageReference Include="System.Text.Json">
<Version>4.7.2</Version>
<Version>5.0.2</Version>
</PackageReference>
<PackageReference Include="System.Xml.XPath.XmlDocument">
<Version>4.3.0</Version>
@ -211,6 +211,7 @@
<Compile Include="UI\Controls\Test_UniformGrid_Dimensions.cs" />
<Compile Include="UI\Controls\Test_WrapPanel_Visibility.cs" />
<Compile Include="UI\Controls\Test_WrapPanel_BasicLayout.cs" />
<Compile Include="UI\Extensions\Test_VisualExtensions.cs" />
<Compile Include="UI\Person.cs" />
<Compile Include="UI\Test_AdvancedCollectionView.cs" />
<Compile Include="UnitTestApp.xaml.cs">
@ -547,4 +548,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>