Skip to content

Commit 5c5c487

Browse files
committed
Merge branch 'main' into winui
# Conflicts: # CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.cs # CommunityToolkit.WinUI.UI.Controls.Primitives/ConstrainedBox/ConstrainedBox.Properties.cs # CommunityToolkit.WinUI.UI.Controls.Primitives/ConstrainedBox/ConstrainedBox.cs # Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj # UITests/UITests.Tests.Shared/Controls/GridSplitterTest.cs # UITests/UITests.Tests.Shared/Controls/RichSuggestBoxTest.cs # UITests/UITests.Tests.Shared/UITestBase.cs # UITests/UITests.Tests.TAEF/UITests.App.dependencies.Debug.txt # UITests/UITests.Tests.TAEF/UITests.App.dependencies.Release.txt # Windows Community Toolkit.sln # build/Windows.Toolkit.WinUI.Controls.targets
2 parents 323e006 + 7816189 commit 5c5c487

File tree

30 files changed

+460
-78
lines changed

30 files changed

+460
-78
lines changed

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
443443
AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.DebuggerNonUserCode")))),
444444
AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage")))))
445445
.AddAttributeLists(validationAttributes.Select(static a => AttributeList(SingletonSeparatedList(a))).ToArray())
446-
.WithLeadingTrivia(leadingTrivia)
446+
.WithLeadingTrivia(leadingTrivia.Where(static trivia => !trivia.IsKind(SyntaxKind.RegionDirectiveTrivia) && !trivia.IsKind(SyntaxKind.EndRegionDirectiveTrivia)))
447447
.AddModifiers(Token(SyntaxKind.PublicKeyword))
448448
.AddAccessorListAccessors(
449449
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
@@ -459,7 +459,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
459459
/// <param name="fieldSymbol">The input <see cref="IFieldSymbol"/> instance to process.</param>
460460
/// <returns>The generated property name for <paramref name="fieldSymbol"/>.</returns>
461461
[Pure]
462-
private static string GetGeneratedPropertyName(IFieldSymbol fieldSymbol)
462+
public static string GetGeneratedPropertyName(IFieldSymbol fieldSymbol)
463463
{
464464
string propertyName = fieldSymbol.Name;
465465

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.cs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
using static CommunityToolkit.Mvvm.SourceGenerators.Diagnostics.DiagnosticDescriptors;
1717
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
1818

19+
#pragma warning disable SA1008
20+
1921
namespace CommunityToolkit.Mvvm.SourceGenerators
2022
{
2123
/// <summary>
@@ -46,8 +48,10 @@ public void Execute(GeneratorExecutionContext context)
4648
context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null));
4749
}
4850

49-
// Get the symbol for the ValidationAttribute type
50-
INamedTypeSymbol validationSymbol = context.Compilation.GetTypeByMetadataName("System.ComponentModel.DataAnnotations.ValidationAttribute")!;
51+
// Get the symbol for the required attributes
52+
INamedTypeSymbol
53+
validationSymbol = context.Compilation.GetTypeByMetadataName("System.ComponentModel.DataAnnotations.ValidationAttribute")!,
54+
observablePropertySymbol = context.Compilation.GetTypeByMetadataName("Microsoft.Toolkit.Mvvm.ComponentModel.ObservablePropertyAttribute")!;
5155

5256
// Prepare the attributes to add to the first class declaration
5357
AttributeListSyntax[] classAttributes = new[]
@@ -145,14 +149,14 @@ public void Execute(GeneratorExecutionContext context)
145149
Parameter(Identifier("obj")).WithType(PredefinedType(Token(SyntaxKind.ObjectKeyword))))
146150
.WithBody(Block(
147151
LocalDeclarationStatement(
148-
VariableDeclaration(IdentifierName("var")) // Cannot Token(SyntaxKind.VarKeyword) here (throws an ArgumentException)
152+
VariableDeclaration(IdentifierName("var")) // Cannot use Token(SyntaxKind.VarKeyword) here (throws an ArgumentException)
149153
.AddVariables(
150154
VariableDeclarator(Identifier("instance"))
151155
.WithInitializer(EqualsValueClause(
152156
CastExpression(
153157
IdentifierName(classSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)),
154158
IdentifierName("obj")))))))
155-
.AddStatements(EnumerateValidationStatements(classSymbol, validationSymbol).ToArray())),
159+
.AddStatements(EnumerateValidationStatements(classSymbol, validationSymbol, observablePropertySymbol).ToArray())),
156160
ReturnStatement(IdentifierName("ValidateAllProperties")))))))
157161
.NormalizeWhitespace()
158162
.ToFullString();
@@ -166,28 +170,47 @@ public void Execute(GeneratorExecutionContext context)
166170
}
167171

168172
/// <summary>
169-
/// Gets a sequence of statements to validate declared properties.
173+
/// Gets a sequence of statements to validate declared properties (including generated ones).
170174
/// </summary>
171175
/// <param name="classSymbol">The input <see cref="INamedTypeSymbol"/> instance to process.</param>
172176
/// <param name="validationSymbol">The type symbol for the <c>ValidationAttribute</c> type.</param>
177+
/// <param name="observablePropertySymbol">The type symbol for the <c>ObservablePropertyAttribute</c> type.</param>
173178
/// <returns>The sequence of <see cref="StatementSyntax"/> instances to validate declared properties.</returns>
174179
[Pure]
175-
private static IEnumerable<StatementSyntax> EnumerateValidationStatements(INamedTypeSymbol classSymbol, INamedTypeSymbol validationSymbol)
180+
private static IEnumerable<StatementSyntax> EnumerateValidationStatements(INamedTypeSymbol classSymbol, INamedTypeSymbol validationSymbol, INamedTypeSymbol observablePropertySymbol)
176181
{
177-
foreach (var propertySymbol in classSymbol.GetMembers().OfType<IPropertySymbol>())
182+
foreach (var memberSymbol in classSymbol.GetMembers())
178183
{
179-
if (propertySymbol.IsIndexer)
184+
if (memberSymbol is not (IPropertySymbol { IsIndexer: false } or IFieldSymbol))
180185
{
181186
continue;
182187
}
183188

184-
ImmutableArray<AttributeData> attributes = propertySymbol.GetAttributes();
189+
ImmutableArray<AttributeData> attributes = memberSymbol.GetAttributes();
185190

191+
// Also include fields that are annotated with [ObservableProperty]. This is necessary because
192+
// all generators run in an undefined order and looking at the same original compilation, so the
193+
// current one wouldn't be able to see generated properties from other generators directly.
194+
if (memberSymbol is IFieldSymbol &&
195+
!attributes.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, observablePropertySymbol)))
196+
{
197+
continue;
198+
}
199+
200+
// Skip the current member if there are no validation attributes applied to it
186201
if (!attributes.Any(a => a.AttributeClass?.InheritsFrom(validationSymbol) == true))
187202
{
188203
continue;
189204
}
190205

206+
// Get the target property name either directly or matching the generated one
207+
string propertyName = memberSymbol switch
208+
{
209+
IPropertySymbol propertySymbol => propertySymbol.Name,
210+
IFieldSymbol fieldSymbol => ObservablePropertyGenerator.GetGeneratedPropertyName(fieldSymbol),
211+
_ => throw new InvalidOperationException("Invalid symbol type")
212+
};
213+
191214
// This enumerator produces a sequence of statements as follows:
192215
//
193216
// __ObservableValidatorHelper.ValidateProperty(instance, instance.<PROPERTY_0>, nameof(instance.<PROPERTY_0>));
@@ -207,14 +230,14 @@ private static IEnumerable<StatementSyntax> EnumerateValidationStatements(INamed
207230
MemberAccessExpression(
208231
SyntaxKind.SimpleMemberAccessExpression,
209232
IdentifierName("instance"),
210-
IdentifierName(propertySymbol.Name))),
233+
IdentifierName(propertyName))),
211234
Argument(
212235
InvocationExpression(IdentifierName("nameof"))
213236
.AddArgumentListArguments(Argument(
214237
MemberAccessExpression(
215238
SyntaxKind.SimpleMemberAccessExpression,
216239
IdentifierName("instance"),
217-
IdentifierName(propertySymbol.Name)))))));
240+
IdentifierName(propertyName)))))));
218241
}
219242
}
220243
}

CommunityToolkit.WinUI.SampleApp/SamplePages/InAppNotification/InAppNotificationXaml.bind

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
<Setter Property="Foreground" Value="{ThemeResource ApplicationForegroundThemeBrush}" />
111111
<Setter Property="Width" Value="40" />
112112
<Setter Property="Height" Value="40" />
113+
<Setter Property="Padding" Value="4" />
113114
<Setter Property="UseSystemFocusVisuals" Value="True" />
114115
<Setter Property="HighContrastAdjustment" Value="None" />
115116
<Setter Property="Template">
@@ -264,7 +265,7 @@
264265
VerticalAlignment="Center"
265266
Visibility="{Binding ShowDismissButton, ElementName=ExampleCustomInAppNotification}">
266267
<Button.RenderTransform>
267-
<TranslateTransform x:Name="DismissButtonTransform" X="25" Y="-5"/>
268+
<TranslateTransform x:Name="DismissButtonTransform" X="20" Y="1"/>
268269
</Button.RenderTransform>
269270
</Button>
270271
</Grid>

CommunityToolkit.WinUI.SampleApp/SamplePages/TokenizingTextBox/TokenizingTextBoxPage.xaml.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ public sealed partial class TokenizingTextBoxPage : Page, IXamlRenderListener
8989
private AdvancedCollectionView _acv;
9090
private AdvancedCollectionView _acvEmail;
9191

92-
private ObservableCollection<SampleEmailDataType> _selectedEmails;
92+
public ObservableCollection<SampleDataType> SelectedTokens { get; set; }
93+
94+
public ObservableCollection<SampleEmailDataType> SelectedEmails { get; set; }
9395

9496
public TokenizingTextBoxPage()
9597
{
@@ -111,7 +113,10 @@ public TokenizingTextBoxPage()
111113

112114
public void OnXamlRendered(FrameworkElement control)
113115
{
114-
_selectedEmails = new ObservableCollection<SampleEmailDataType>();
116+
SelectedTokens = new();
117+
SelectedEmails = new();
118+
119+
control.DataContext = this;
115120

116121
if (_ttb != null)
117122
{
@@ -149,7 +154,6 @@ public void OnXamlRendered(FrameworkElement control)
149154
{
150155
_ttbEmail = ttbEmail;
151156

152-
_ttbEmail.ItemsSource = _selectedEmails;
153157
_ttbEmail.ItemClick += EmailTokenItemClick;
154158
_ttbEmail.TokenItemAdding += EmailTokenItemAdding;
155159
_ttbEmail.TokenItemAdded += EmailTokenItemAdded;

CommunityToolkit.WinUI.SampleApp/SamplePages/TokenizingTextBox/TokenizingTextBoxXaml.bind

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
</TextBlock>
3838
<controls:TokenizingTextBox
3939
x:Name="TokenBox"
40+
ItemsSource="{Binding SelectedTokens}"
4041
PlaceholderText="Add Actions"
4142
QueryIcon="{ui:SymbolIconSource Symbol=Setting}"
4243
MaxHeight="104"
@@ -65,14 +66,15 @@
6566
<Run>Current Edit: </Run>
6667
<Run Text="{Binding Text, ElementName=TokenBox}"/>
6768
</TextBlock>
68-
<ItemsControl ItemsSource="{Binding ItemsSource, ElementName=TokenBox}"/>
69+
<ItemsControl ItemsSource="{Binding SelectedTokens}"/>
6970
</StackPanel>
7071

7172
<StackPanel Grid.Row="1">
7273
<TextBlock FontSize="32" Text="Select Email Addresses"
7374
Margin="0,0,0,4"/>
7475
<controls:TokenizingTextBox
7576
x:Name="TokenBoxEmail"
77+
ItemsSource="{Binding SelectedEmails}"
7678
PlaceholderText="Select Names"
7779
MaxHeight="104"
7880
HorizontalAlignment="Stretch"

CommunityToolkit.WinUI.UI.Behaviors/CommunityToolkit.WinUI.UI.Behaviors.csproj

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@
99
<Title>Windows Community Toolkit - UI Behaviors</Title>
1010
<Description>
1111
This library provides UI behaviors built on the XAML behaviors SDK. It is a part of the Windows Community Toolkit.
12-
13-
Behaviors:
14-
- BehaviorBase: Helper for building Behaviors
12+
13+
- Animation: Various helpers for integration with the Toolkit's Animation package.
1514
- AutoFocusBehevior: Sets focus to the associated control.
16-
- FocusBehavior: Sets focus to a specified control.
17-
- ViewportBehavior: Listening for element to enter or exit the ScrollViewer viewport
15+
- AutoSelectBehavior: Selects a TextBox's text automatically.
1816
- FadeHeaderBehavior, QuickReturnHeaderBehavior, StickyHeaderBehavior: Helpers for ListViewBase Header Behavior
17+
- FocusBehavior: Sets focus to a specified control.
18+
- KeyDownTriggerBehavior: Trigger behaviors when a key is pressed.
19+
- ViewportBehavior: Listening for element to enter or exit the ScrollViewer viewport
1920
</Description>
20-
<PackageTags>UI;XAML;Behaviors;Interactivity;Interaction;Focus;Header;Viewport</PackageTags>
21+
<PackageTags>UI;XAML;Behaviors;Interactivity;Interaction;Focus;Header;Viewport;Selection;Focus;KeyDown;Triggers;Viewport</PackageTags>
2122
</PropertyGroup>
2223

2324
<ItemGroup>

CommunityToolkit.WinUI.UI.Controls.Core/CommunityToolkit.WinUI.UI.Controls.Core.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- ImageEx: Images are downloaded asynchronously showing a load indicator and can be stored in a local cache.
1717
- InAppNotification: Show local notifications in your application.
1818
- Loading: Helps to show content with animation to the user while the app is doing some calculation.
19+
- MetadataControl: Control for organizing text based categories with a separator, supports commands.
1920
- RadialProgressBar: Displays progress as a circle getting filled.
2021
- RotatorTile: Rotates through a set of items one-by-one like a live-tile.
2122
- TabbedCommandBar: A command bar that organizes features of an application into a series of tabs.
@@ -29,6 +30,7 @@
2930
Image;Ex ;ImageEx ;
3031
In;App;Notification;InAppNotification;InApp ;
3132
Loading ;
33+
Metadata;Tags;
3234
Radial;Progress;Bar;RadialProgressBar;ProgressBar ;
3335
Rotator;Tile ;RotatorTile ;
3436
Tabbed;Command;Bar ;TabbedCommandBar ;CommandBar ;

CommunityToolkit.WinUI.UI.Controls.Core/InAppNotification/Styles/MSEdgeNotificationStyle.xaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<Setter Property="Foreground" Value="{ThemeResource ApplicationForegroundThemeBrush}" />
4444
<Setter Property="Width" Value="{StaticResource SystemControlMSEdgeNotificationDismissButtonSize}" />
4545
<Setter Property="Height" Value="{StaticResource SystemControlMSEdgeNotificationDismissButtonSize}" />
46+
<Setter Property="Padding" Value="4" />
4647
<Setter Property="UseSystemFocusVisuals" Value="True" />
4748
<Setter Property="HighContrastAdjustment" Value="None" />
4849
<Setter Property="Template">
@@ -150,9 +151,10 @@
150151
FontFamily="Segoe MDL2 Assets"
151152
FontSize="12"
152153
VerticalAlignment="Top"
154+
Padding="4"
153155
Style="{StaticResource DismissTextBlockButtonStyle}">
154156
<Button.RenderTransform>
155-
<TranslateTransform x:Name="DismissButtonTransform" X="25" Y="-5"/>
157+
<TranslateTransform x:Name="DismissButtonTransform" X="20" Y="1"/>
156158
</Button.RenderTransform>
157159
</Button>
158160
</Grid>

CommunityToolkit.WinUI.UI.Controls.Input/CommunityToolkit.WinUI.UI.Controls.Input.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- RadialGauge: Displays a value within a range, using a needle on a circular face.
1616
- RangeSelector: "Double slider" control for range values.
1717
- RemoteDevicePicker: Remote Device Picker Control for Project Rome.
18+
- RichSuggestBox: RichEditBox which supports at mentioning or tags.
1819
- TokenizingTextBox: An AutoSuggestBox like control which places entered input into easily removed containers for contacts or tags.
1920
</Description>
2021
<PackageTags>
@@ -23,6 +24,7 @@
2324
Radial;Gauge ;RadialGauge ;
2425
Range;Selector ;RangeSelector ;
2526
Remote;Device;Picker;RemoteDevicePicker;DevicePicker;RemoteDevice;
27+
RichEditBox;RichSuggestBox;Suggestions;Mentions;Tags;
2628
Tokenizing;Text;Box ;TokenizingTextBox ;TextBox ;
2729
</PackageTags>
2830
</PropertyGroup>

CommunityToolkit.WinUI.UI.Controls.Layout/ListDetailsView/ListDetailsView.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ private void OnSelectedItemChanged(DependencyPropertyChangedEventArgs e)
163163

164164
OnSelectionChanged(new SelectionChangedEventArgs(new List<object> { e.OldValue }, new List<object> { e.NewValue }));
165165
UpdateView(true);
166+
SetFocus(ViewState);
166167
}
167168

168169
private void OnLoaded(object sender, RoutedEventArgs e)
@@ -413,7 +414,7 @@ private void FocusFirstFocusableElementInDetails()
413414
/// </summary>
414415
private void FocusItemList()
415416
{
416-
if (GetTemplateChild("PartMainList") is Control list)
417+
if (GetTemplateChild(PartMainList) is Control list)
417418
{
418419
list.Focus(FocusState.Programmatic);
419420
}

0 commit comments

Comments
 (0)