Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TemplatePart XAML diagnostics #14180

Merged
merged 6 commits into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ indent_size = 2
avalonia_xaml_diagnostic.AVLN2203.severity = error
# StyleInMergedDictionaries
avalonia_xaml_diagnostic.AVLN2204.severity = error
# RequiredTemplatePartMissing
avalonia_xaml_diagnostic.AVLN2205.severity = error
# OptionalTemplatePartMissing
avalonia_xaml_diagnostic.AVLN2206.severity = info
# TemplatePartWrongType
avalonia_xaml_diagnostic.AVLN2207.severity = error
# Obsolete
avalonia_xaml_diagnostic.AVLN5001.severity = error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
<ColumnDefinition Width="Auto" SharedSizeGroup="HeaderCol" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{TemplateBinding Header}"
<ContentPresenter x:Name="PART_HeaderPresenter"
Content="{TemplateBinding Header}"
Grid.Column="0"
VerticalAlignment="Center" />
<ContentPresenter Content="{TemplateBinding Content}"
<ContentPresenter x:Name="PART_ContentPresenter"
Content="{TemplateBinding Content}"
Grid.Column="1"
VerticalAlignment="Center" />
</Grid>
Expand Down
9 changes: 6 additions & 3 deletions src/Avalonia.Base/Controls/Metadata/TemplatePartAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

using System;

#nullable enable

namespace Avalonia.Controls.Metadata
{
/// <summary>
Expand All @@ -17,7 +15,7 @@ namespace Avalonia.Controls.Metadata
/// Style authors should be able to identify the part type used for styling the specific control.
/// The part is usually required in the style and should have a specific predefined name.
/// </remarks>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class TemplatePartAttribute : Attribute
{
/// <summary>
Expand Down Expand Up @@ -51,5 +49,10 @@ public TemplatePartAttribute(string name, Type type)
/// in <see cref="Name"/>.
/// </summary>
public Type Type { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the template part is mandatory to be present in the template.
/// </summary>
public bool IsRequired { get; set; }
}
}
3 changes: 2 additions & 1 deletion src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@
<ColumnDefinition Width="Auto" MinWidth="{DynamicResource DataGridSortIconMinWidth}" />
</Grid.ColumnDefinitions>

<ContentPresenter Content="{TemplateBinding Content}"
<ContentPresenter x:Name="PART_ContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />

<Path Name="SortIcon"
Expand Down
3 changes: 2 additions & 1 deletion src/Avalonia.Controls.DataGrid/Themes/Simple.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
ColumnDefinitions="*,Auto">
<ContentPresenter Content="{TemplateBinding Content}"
<ContentPresenter x:Name="PART_ContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />

<Path Name="SortIcon"
Expand Down
33 changes: 21 additions & 12 deletions src/Avalonia.Controls/Chrome/CaptionButtons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,28 @@ protected virtual void OnToggleFullScreen()
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);

if (e.NameScope.Find<Button>(PART_CloseButton) is { } closeButton)
{
closeButton.Click += (sender, e) => OnClose();
}

var closeButton = e.NameScope.Get<Button>(PART_CloseButton);
var restoreButton = e.NameScope.Get<Button>(PART_RestoreButton);
var minimizeButton = e.NameScope.Get<Button>(PART_MinimizeButton);
var fullScreenButton = e.NameScope.Get<Button>(PART_FullScreenButton);

closeButton.Click += (sender, e) => OnClose();
restoreButton.Click += (sender, e) => OnRestore();
minimizeButton.Click += (sender, e) => OnMinimize();
fullScreenButton.Click += (sender, e) => OnToggleFullScreen();

restoreButton.IsEnabled = HostWindow?.CanResize ?? true;
_restoreButton = restoreButton;
if (e.NameScope.Find<Button>(PART_RestoreButton) is { } restoreButton)
{
restoreButton.Click += (sender, e) => OnRestore();
restoreButton.IsEnabled = HostWindow?.CanResize ?? true;
_restoreButton = restoreButton;
}

if (e.NameScope.Find<Button>(PART_MinimizeButton) is { } minimizeButton)
{
minimizeButton.Click += (sender, e) => OnMinimize();
}

if (e.NameScope.Find<Button>(PART_FullScreenButton) is { } fullScreenButton)
{
fullScreenButton.Click += (sender, e) => OnToggleFullScreen();
}
}
}
}
2 changes: 1 addition & 1 deletion src/Avalonia.Controls/Chrome/TitleBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Avalonia.Controls.Chrome
/// <summary>
/// Draws a titlebar when managed client decorations are enabled.
/// </summary>
[TemplatePart("PART_CaptionButtons", typeof(CaptionButtons))]
[TemplatePart("PART_CaptionButtons", typeof(CaptionButtons), IsRequired = true)]
[PseudoClasses(":minimized", ":normal", ":maximized", ":fullscreen")]
public class TitleBar : TemplatedControl
{
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Controls/ComboBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Avalonia.Controls
/// <summary>
/// A drop-down list control.
/// </summary>
[TemplatePart("PART_Popup", typeof(Popup))]
[TemplatePart("PART_Popup", typeof(Popup), IsRequired = true)]
[PseudoClasses(pcDropdownOpen, pcPressed)]
public class ComboBox : SelectingItemsControl
{
Expand Down
16 changes: 8 additions & 8 deletions src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ namespace Avalonia.Controls
/// Defines the presenter used for selecting a date for a
/// <see cref="DatePicker"/>
/// </summary>
[TemplatePart("PART_AcceptButton", typeof(Button))]
[TemplatePart("PART_AcceptButton", typeof(Button), IsRequired = true)]
[TemplatePart("PART_DayDownButton", typeof(RepeatButton))]
[TemplatePart("PART_DayHost", typeof(Panel))]
[TemplatePart("PART_DaySelector", typeof(DateTimePickerPanel))]
[TemplatePart("PART_DayHost", typeof(Panel), IsRequired = true)]
[TemplatePart("PART_DaySelector", typeof(DateTimePickerPanel), IsRequired = true)]
[TemplatePart("PART_DayUpButton", typeof(RepeatButton))]
[TemplatePart("PART_DismissButton", typeof(Button))]
[TemplatePart("PART_FirstSpacer", typeof(Rectangle))]
[TemplatePart("PART_MonthDownButton", typeof(RepeatButton))]
[TemplatePart("PART_MonthHost", typeof(Panel))]
[TemplatePart("PART_MonthSelector", typeof(DateTimePickerPanel))]
[TemplatePart("PART_MonthHost", typeof(Panel), IsRequired = true)]
[TemplatePart("PART_MonthSelector", typeof(DateTimePickerPanel), IsRequired = true)]
[TemplatePart("PART_MonthUpButton", typeof(RepeatButton))]
[TemplatePart("PART_PickerContainer", typeof(Grid))]
[TemplatePart("PART_PickerContainer", typeof(Grid), IsRequired = true)]
[TemplatePart("PART_SecondSpacer", typeof(Rectangle))]
[TemplatePart("PART_YearDownButton", typeof(RepeatButton))]
[TemplatePart("PART_YearHost", typeof(Panel))]
[TemplatePart("PART_YearSelector", typeof(DateTimePickerPanel))]
[TemplatePart("PART_YearHost", typeof(Panel), IsRequired = true)]
[TemplatePart("PART_YearSelector", typeof(DateTimePickerPanel), IsRequired = true)]
[TemplatePart("PART_YearUpButton", typeof(RepeatButton))]
public class DatePickerPresenter : PickerPresenterBase
{
Expand Down
14 changes: 7 additions & 7 deletions src/Avalonia.Controls/DateTimePickers/TimePickerPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ namespace Avalonia.Controls
/// Defines the presenter used for selecting a time. Intended for use with
/// <see cref="TimePicker"/> but can be used independently
/// </summary>
[TemplatePart("PART_AcceptButton", typeof(Button))]
[TemplatePart("PART_AcceptButton", typeof(Button), IsRequired = true)]
[TemplatePart("PART_DismissButton", typeof(Button))]
[TemplatePart("PART_HourDownButton", typeof(RepeatButton))]
[TemplatePart("PART_HourSelector", typeof(DateTimePickerPanel))]
[TemplatePart("PART_HourSelector", typeof(DateTimePickerPanel), IsRequired = true)]
[TemplatePart("PART_HourUpButton", typeof(RepeatButton))]
[TemplatePart("PART_MinuteDownButton", typeof(RepeatButton))]
[TemplatePart("PART_MinuteSelector", typeof(DateTimePickerPanel))]
[TemplatePart("PART_MinuteSelector", typeof(DateTimePickerPanel), IsRequired = true)]
[TemplatePart("PART_MinuteUpButton", typeof(RepeatButton))]
[TemplatePart("PART_PeriodDownButton", typeof(RepeatButton))]
[TemplatePart("PART_PeriodHost", typeof(Panel))]
[TemplatePart("PART_PeriodSelector", typeof(DateTimePickerPanel))]
[TemplatePart("PART_PeriodHost", typeof(Panel), IsRequired = true)]
[TemplatePart("PART_PeriodSelector", typeof(DateTimePickerPanel), IsRequired = true)]
[TemplatePart("PART_PeriodUpButton", typeof(RepeatButton))]
[TemplatePart("PART_PickerContainer", typeof(Grid))]
[TemplatePart("PART_SecondSpacer", typeof(Rectangle))]
[TemplatePart("PART_PickerContainer", typeof(Grid), IsRequired = true)]
[TemplatePart("PART_SecondSpacer", typeof(Rectangle), IsRequired = true)]
public class TimePickerPresenter : PickerPresenterBase
{
/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Controls/NumericUpDown/NumericUpDown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace Avalonia.Controls
/// Control that represents a TextBox with button spinners that allow incrementing and decrementing numeric values.
/// </summary>
[TemplatePart("PART_Spinner", typeof(Spinner))]
[TemplatePart("PART_TextBox", typeof(TextBox))]
[TemplatePart("PART_TextBox", typeof(TextBox), IsRequired = true)]
public class NumericUpDown : TemplatedControl
{
/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using Avalonia.Collections;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Data;
Expand All @@ -10,6 +11,7 @@ namespace Avalonia.Controls.Primitives
/// <summary>
/// Represents an <see cref="ItemsControl"/> with a related header.
/// </summary>
[TemplatePart("PART_HeaderPresenter", typeof(ContentPresenter))]
public class HeaderedItemsControl : ItemsControl, IContentPresenterHost
{
private IDisposable? _itemsBinding;
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Controls/ProgressBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Avalonia.Controls
/// <summary>
/// A control used to indicate the progress of an operation.
/// </summary>
[TemplatePart("PART_Indicator", typeof(Border))]
[TemplatePart("PART_Indicator", typeof(Border), IsRequired = true)]
[PseudoClasses(":vertical", ":horizontal", ":indeterminate")]
public class ProgressBar : RangeBase
{
Expand Down
9 changes: 3 additions & 6 deletions src/Avalonia.Controls/Slider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public enum TickPlacement
/// </summary>
[TemplatePart("PART_DecreaseButton", typeof(Button))]
[TemplatePart("PART_IncreaseButton", typeof(Button))]
[TemplatePart("PART_Track", typeof(Track))]
[TemplatePart("PART_Track", typeof(Track), IsRequired = true)]
[PseudoClasses(":vertical", ":horizontal", ":pressed")]
public class Slider : RangeBase
{
Expand Down Expand Up @@ -204,13 +204,10 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
_pointerMovedDispose?.Dispose();

_decreaseButton = e.NameScope.Find<Button>("PART_DecreaseButton");
_track = e.NameScope.Find<Track>("PART_Track");
_track = e.NameScope.Get<Track>("PART_Track");
_increaseButton = e.NameScope.Find<Button>("PART_IncreaseButton");

if (_track != null)
{
_track.IgnoreThumbDrag = true;
}
_track.IgnoreThumbDrag = true;

if (_decreaseButton != null)
{
Expand Down
1 change: 1 addition & 0 deletions src/Avalonia.Controls/TabControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Avalonia.Controls
/// A tab control that displays a tab strip along with the content of the selected tab.
/// </summary>
[TemplatePart("PART_ItemsPresenter", typeof(ItemsPresenter))]
[TemplatePart("PART_SelectedContentHost", typeof(ContentPresenter))]
public class TabControl : SelectingItemsControl, IContentPresenterHost
{
private object? _selectedContent;
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Controls/TextBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Avalonia.Controls
/// <summary>
/// Represents a control that can be used to display or edit unformatted text.
/// </summary>
[TemplatePart("PART_TextPresenter", typeof(TextPresenter))]
[TemplatePart("PART_TextPresenter", typeof(TextPresenter), IsRequired = true)]
[TemplatePart("PART_ScrollViewer", typeof(ScrollViewer))]
[PseudoClasses(":empty")]
public class TextBox : TemplatedControl, UndoRedoHelper<TextBox.UndoRedoState>.IUndoRedoHost
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Controls/ToggleSwitch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Avalonia.Controls
/// <summary>
/// A Toggle Switch control.
/// </summary>
[TemplatePart("PART_MovingKnobs", typeof(Panel))]
[TemplatePart("PART_MovingKnobs", typeof(Panel), IsRequired = true)]
[TemplatePart("PART_OffContentPresenter", typeof(ContentPresenter))]
[TemplatePart("PART_OnContentPresenter", typeof(ContentPresenter))]
[TemplatePart("PART_SwitchKnob", typeof(Panel))]
Expand Down
4 changes: 2 additions & 2 deletions src/Avalonia.Dialogs/ManagedFileChooser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

namespace Avalonia.Dialogs
{
[TemplatePart("PART_QuickLinks", typeof(Control))]
[TemplatePart("PART_Files", typeof(ListBox))]
[TemplatePart("PART_QuickLinks", typeof(Control), IsRequired = true)]
[TemplatePart("PART_Files", typeof(ListBox), IsRequired = true)]
public class ManagedFileChooser : TemplatedControl
{
private Control? _quickLinksRoot;
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Themes.Fluent/Controls/CalendarButton.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<!-- To mimic WinUI SystemFocusVisual, Focus visual is drawn outside the bounds of the item -->
<Border Name="Root" Background="{TemplateBinding Background}"
BorderThickness="0" ClipToBounds="True">
<ContentPresenter Name="Content"
<ContentPresenter Name="PART_ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Expand Down
12 changes: 6 additions & 6 deletions src/Avalonia.Themes.Fluent/Controls/CalendarDayButton.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@
<Border Name="Root" Background="{TemplateBinding Background}"
BorderThickness="0" ClipToBounds="True">

<ContentControl Name="Content"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}" />
<ContentPresenter Name="PART_ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}" />

</Border>

Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Themes.Fluent/Controls/CalendarItem.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<Setter Property="Template">
<ControlTemplate>
<!-- HCA was changed here to ensure nav arrows display correctly -->
<ContentPresenter Name="Text" Background="{TemplateBinding Background}"
<ContentPresenter Name="PART_ContentPresenter" Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource CalendarViewNavigationButtonBorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Themes.Fluent/Controls/CheckBox.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
</Panel>
</Viewbox>
</Grid>
<ContentPresenter x:Name="ContentPresenter"
<ContentPresenter x:Name="PART_ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
that appear opaque. Not sure how MS does it though I suspect this is it
but source isn't MIT yet, so this is my solution -->
<Border Background="{TemplateBinding Background}">
<ContentPresenter x:Name="ContentPresenter"
<ContentPresenter x:Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource DateTimePickerFlyoutButtonBorderBrush}"
BorderThickness="{DynamicResource DateTimeFlyoutButtonBorderThickness}"
Expand Down
3 changes: 2 additions & 1 deletion src/Avalonia.Themes.Fluent/Controls/FlyoutPresenter.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
CornerRadius="{TemplateBinding CornerRadius}">
<ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
<ContentPresenter Content="{TemplateBinding Content}"
<ContentPresenter x:Name="PART_ContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Themes.Fluent/Controls/NotificationCard.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
ClipToBounds="True">
<DockPanel>
<Panel x:Name="PART_HeaderBar" Height="4" Background="{DynamicResource NotificationCardProgressBackgroundBrush}" DockPanel.Dock="Top" />
<ContentControl Name="PART_Content" MinHeight="64" Content="{TemplateBinding Content}" />
<ContentPresenter Name="PART_ContentPresenter" MinHeight="64" Content="{TemplateBinding Content}" />
</DockPanel>
</Border>
</Border>
Expand Down
3 changes: 2 additions & 1 deletion src/Avalonia.Themes.Fluent/Controls/ScrollBar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
<Setter Property="TextElement.Foreground" Value="{DynamicResource ScrollBarButtonArrowForeground}"/>
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter Background="{DynamicResource ScrollBarButtonBackground}"
<ContentPresenter x:Name="PART_ContentPresenter"
Background="{DynamicResource ScrollBarButtonBackground}"
BorderBrush="{DynamicResource ScrollBarButtonBorderBrush}"
Content="{TemplateBinding Content}"/>
</ControlTemplate>
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Themes.Simple/Controls/CalendarButton.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
Opacity="0.5" />

<!-- Focusable="False" -->
<ContentPresenter Name="Content"
<ContentPresenter x:Name="PART_ContentPresenter"
Margin="1,0,1,1"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Expand Down
Loading
Loading