Skip to content

Commit c877c1b

Browse files
maxkatz6grokys
authored andcommitted
Merge pull request AvaloniaUI#7911 from robloo/add-template-parts
Add Template Part Attributes to Controls
1 parent 2ad6d64 commit c877c1b

27 files changed

+129
-2
lines changed

src/Avalonia.Controls/AutoCompleteBox.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ public enum AutoCompleteFilterMode
252252
/// drop-down that contains possible matches based on the input in the text
253253
/// box.
254254
/// </summary>
255+
[TemplatePart(ElementPopup, typeof(Popup))]
256+
[TemplatePart(ElementSelector, typeof(SelectingItemsControl))]
257+
[TemplatePart(ElementSelectionAdapter, typeof(ISelectionAdapter))]
258+
[TemplatePart(ElementTextBox, typeof(TextBox))]
255259
[PseudoClasses(":dropdownopen")]
256260
public class AutoCompleteBox : TemplatedControl
257261
{

src/Avalonia.Controls/ButtonSpinner.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public enum Location
1616
/// <summary>
1717
/// Represents a spinner control that includes two Buttons.
1818
/// </summary>
19+
[TemplatePart("PART_DecreaseButton", typeof(Button))]
20+
[TemplatePart("PART_IncreaseButton", typeof(Button))]
1921
[PseudoClasses(":left", ":right")]
2022
public class ButtonSpinner : Spinner
2123
{

src/Avalonia.Controls/Calendar/Calendar.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System;
77
using System.Collections.ObjectModel;
88
using System.Diagnostics;
9+
using Avalonia.Controls.Metadata;
910
using Avalonia.Controls.Primitives;
1011
using Avalonia.Data;
1112
using Avalonia.Input;
@@ -222,6 +223,8 @@ public CalendarModeChangedEventArgs(CalendarMode oldMode, CalendarMode newMode)
222223
/// element in XAML.
223224
/// </para>
224225
/// </remarks>
226+
[TemplatePart(PART_ElementMonth, typeof(CalendarItem))]
227+
[TemplatePart(PART_ElementRoot, typeof(Panel))]
225228
public class Calendar : TemplatedControl
226229
{
227230
internal const int RowsPerMonth = 7;
@@ -261,6 +264,7 @@ internal CalendarItem MonthControl
261264
AvaloniaProperty.Register<Calendar, DayOfWeek>(
262265
nameof(FirstDayOfWeek),
263266
defaultValue: DateTimeHelper.GetCurrentDateFormat().FirstDayOfWeek);
267+
264268
/// <summary>
265269
/// Gets or sets the day that is considered the beginning of the week.
266270
/// </summary>
@@ -273,6 +277,7 @@ public DayOfWeek FirstDayOfWeek
273277
get { return GetValue(FirstDayOfWeekProperty); }
274278
set { SetValue(FirstDayOfWeekProperty, value); }
275279
}
280+
276281
/// <summary>
277282
/// FirstDayOfWeekProperty property changed handler.
278283
/// </summary>
@@ -289,6 +294,7 @@ private void OnFirstDayOfWeekChanged(AvaloniaPropertyChangedEventArgs e)
289294
throw new ArgumentOutOfRangeException("d", "Invalid DayOfWeek");
290295
}
291296
}
297+
292298
/// <summary>
293299
/// Inherited code: Requires comment.
294300
/// </summary>
@@ -311,6 +317,7 @@ private static bool IsValidFirstDayOfWeek(object value)
311317
AvaloniaProperty.Register<Calendar, bool>(
312318
nameof(IsTodayHighlighted),
313319
defaultValue: true);
320+
314321
/// <summary>
315322
/// Gets or sets a value indicating whether the current date is
316323
/// highlighted.
@@ -324,6 +331,7 @@ public bool IsTodayHighlighted
324331
get { return GetValue(IsTodayHighlightedProperty); }
325332
set { SetValue(IsTodayHighlightedProperty, value); }
326333
}
334+
327335
/// <summary>
328336
/// IsTodayHighlightedProperty property changed handler.
329337
/// </summary>
@@ -343,6 +351,7 @@ private void OnIsTodayHighlightedChanged(AvaloniaPropertyChangedEventArgs e)
343351

344352
public static readonly StyledProperty<IBrush> HeaderBackgroundProperty =
345353
AvaloniaProperty.Register<Calendar, IBrush>(nameof(HeaderBackground));
354+
346355
public IBrush HeaderBackground
347356
{
348357
get { return GetValue(HeaderBackgroundProperty); }
@@ -367,6 +376,7 @@ public CalendarMode DisplayMode
367376
get { return GetValue(DisplayModeProperty); }
368377
set { SetValue(DisplayModeProperty, value); }
369378
}
379+
370380
/// <summary>
371381
/// DisplayModeProperty property changed handler.
372382
/// </summary>
@@ -424,6 +434,7 @@ private static bool IsValidDisplayMode(CalendarMode mode)
424434
|| mode == CalendarMode.Year
425435
|| mode == CalendarMode.Decade;
426436
}
437+
427438
private void OnDisplayModeChanged(CalendarModeChangedEventArgs args)
428439
{
429440
DisplayModeChanged?.Invoke(this, args);
@@ -433,6 +444,7 @@ private void OnDisplayModeChanged(CalendarModeChangedEventArgs args)
433444
AvaloniaProperty.Register<Calendar, CalendarSelectionMode>(
434445
nameof(SelectionMode),
435446
defaultValue: CalendarSelectionMode.SingleDate);
447+
436448
/// <summary>
437449
/// Gets or sets a value that indicates what kind of selections are
438450
/// allowed.
@@ -457,6 +469,7 @@ public CalendarSelectionMode SelectionMode
457469
get { return GetValue(SelectionModeProperty); }
458470
set { SetValue(SelectionModeProperty, value); }
459471
}
472+
460473
private void OnSelectionModeChanged(AvaloniaPropertyChangedEventArgs e)
461474
{
462475
if (IsValidSelectionMode(e.NewValue))
@@ -471,6 +484,7 @@ private void OnSelectionModeChanged(AvaloniaPropertyChangedEventArgs e)
471484
throw new ArgumentOutOfRangeException("d", "Invalid SelectionMode");
472485
}
473486
}
487+
474488
/// <summary>
475489
/// Inherited code: Requires comment.
476490
/// </summary>
@@ -492,6 +506,7 @@ private static bool IsValidSelectionMode(object value)
492506
o => o.SelectedDate,
493507
(o, v) => o.SelectedDate = v,
494508
defaultBindingMode: BindingMode.TwoWay);
509+
495510
/// <summary>
496511
/// Gets or sets the currently selected date.
497512
/// </summary>
@@ -720,6 +735,7 @@ internal DateTime SelectedYear
720735
o => o.DisplayDate,
721736
(o, v) => o.DisplayDate = v,
722737
defaultBindingMode: BindingMode.TwoWay);
738+
723739
/// <summary>
724740
/// Gets or sets the date to display.
725741
/// </summary>
@@ -1959,13 +1975,15 @@ internal void ProcessPageUpKey(bool shift)
19591975
}
19601976
}
19611977
}
1978+
19621979
private void Calendar_KeyUp(KeyEventArgs e)
19631980
{
19641981
if (!e.Handled && (e.Key == Key.LeftShift || e.Key == Key.RightShift))
19651982
{
19661983
ProcessShiftKeyUp();
19671984
}
19681985
}
1986+
19691987
internal void ProcessShiftKeyUp()
19701988
{
19711989
if (_isShiftPressed && (SelectionMode == CalendarSelectionMode.SingleRange || SelectionMode == CalendarSelectionMode.MultipleRange))
@@ -2014,6 +2032,7 @@ protected override void OnGotFocus(GotFocusEventArgs e)
20142032
}
20152033
}
20162034
}
2035+
20172036
protected override void OnLostFocus(RoutedEventArgs e)
20182037
{
20192038
base.OnLostFocus(e);
@@ -2040,6 +2059,7 @@ protected override void OnLostFocus(RoutedEventArgs e)
20402059
}
20412060
}
20422061
}
2062+
20432063
/// <summary>
20442064
/// Called when the IsEnabled property changes.
20452065
/// </summary>
@@ -2084,6 +2104,7 @@ public Calendar()
20842104

20852105
private const string PART_ElementRoot = "Root";
20862106
private const string PART_ElementMonth = "CalendarItem";
2107+
20872108
/// <summary>
20882109
/// Builds the visual tree for the
20892110
/// <see cref="T:System.Windows.Controls.Calendar" /> when a new

src/Avalonia.Controls/Calendar/CalendarDatePicker.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Collections.ObjectModel;
88
using System.Diagnostics;
99
using System.Globalization;
10+
using Avalonia.Controls.Metadata;
1011
using Avalonia.Controls.Primitives;
1112
using Avalonia.Data;
1213
using Avalonia.Input;
@@ -116,6 +117,10 @@ public enum CalendarDatePickerFormat
116117
Custom = 2
117118
}
118119

120+
[TemplatePart(ElementButton, typeof(Button))]
121+
[TemplatePart(ElementCalendar, typeof(Calendar))]
122+
[TemplatePart(ElementPopup, typeof(Popup))]
123+
[TemplatePart(ElementTextBox, typeof(TextBox))]
119124
public class CalendarDatePicker : TemplatedControl
120125
{
121126
private const string ElementTextBox = "PART_TextBox";

src/Avalonia.Controls/Calendar/CalendarItem.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ namespace Avalonia.Controls.Primitives
1919
/// Represents the currently displayed month or year on a
2020
/// <see cref="T:Avalonia.Controls.Calendar" />.
2121
/// </summary>
22+
[TemplatePart(PART_ElementHeaderButton, typeof(Button))]
23+
[TemplatePart(PART_ElementMonthView, typeof(Grid))]
24+
[TemplatePart(PART_ElementNextButton, typeof(Button))]
25+
[TemplatePart(PART_ElementPreviousButton, typeof(Button))]
26+
[TemplatePart(PART_ElementYearView, typeof(Grid))]
2227
[PseudoClasses(":calendardisabled")]
2328
public sealed class CalendarItem : TemplatedControl
2429
{

src/Avalonia.Controls/Chrome/CaptionButtons.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ namespace Avalonia.Controls.Chrome
1010
/// <summary>
1111
/// Draws window minimize / maximize / close buttons in a <see cref="TitleBar"/> when managed client decorations are enabled.
1212
/// </summary>
13+
[TemplatePart("PART_CloseButton", typeof(Panel))]
14+
[TemplatePart("PART_RestoreButton", typeof(Panel))]
15+
[TemplatePart("PART_MinimiseButton", typeof(Panel))]
16+
[TemplatePart("PART_FullScreenButton", typeof(Panel))]
1317
[PseudoClasses(":minimized", ":normal", ":maximized", ":fullscreen")]
1418
public class CaptionButtons : TemplatedControl
1519
{

src/Avalonia.Controls/Chrome/TitleBar.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace Avalonia.Controls.Chrome
1010
/// <summary>
1111
/// Draws a titlebar when managed client decorations are enabled.
1212
/// </summary>
13+
[TemplatePart("PART_CaptionButtons", typeof(CaptionButtons))]
1314
[PseudoClasses(":minimized", ":normal", ":maximized", ":fullscreen")]
1415
public class TitleBar : TemplatedControl
1516
{

src/Avalonia.Controls/ComboBox.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
using Avalonia.Media;
1515
using Avalonia.Threading;
1616
using Avalonia.VisualTree;
17+
using Avalonia.Controls.Metadata;
1718

1819
namespace Avalonia.Controls
1920
{
2021
/// <summary>
2122
/// A drop-down list control.
2223
/// </summary>
24+
[TemplatePart("PART_Popup", typeof(Popup))]
2325
public class ComboBox : SelectingItemsControl
2426
{
2527
/// <summary>

src/Avalonia.Controls/ContentControl.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Avalonia.Collections;
2+
using Avalonia.Controls.Metadata;
23
using Avalonia.Controls.Mixins;
34
using Avalonia.Controls.Presenters;
45
using Avalonia.Controls.Primitives;
@@ -12,6 +13,7 @@ namespace Avalonia.Controls
1213
/// <summary>
1314
/// Displays <see cref="Content"/> according to a <see cref="FuncDataTemplate"/>.
1415
/// </summary>
16+
[TemplatePart("PART_ContentPresenter", typeof(IContentPresenter))]
1517
public class ContentControl : TemplatedControl, IContentControl, IContentPresenterHost
1618
{
1719
/// <summary>

src/Avalonia.Controls/DateTimePickers/DatePicker.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ namespace Avalonia.Controls
1414
/// <summary>
1515
/// A control to allow the user to select a date
1616
/// </summary>
17+
[TemplatePart("ButtonContentGrid", typeof(Grid))]
18+
[TemplatePart("DayText", typeof(TextBlock))]
19+
[TemplatePart("FirstSpacer", typeof(Rectangle))]
20+
[TemplatePart("FlyoutButton", typeof(Button))]
21+
[TemplatePart("MonthText", typeof(TextBlock))]
22+
[TemplatePart("PickerPresenter", typeof(DatePickerPresenter))]
23+
[TemplatePart("Popup", typeof(Popup))]
24+
[TemplatePart("SecondSpacer", typeof(Rectangle))]
25+
[TemplatePart("YearText", typeof(TextBlock))]
1726
[PseudoClasses(":hasnodate")]
1827
public class DatePicker : TemplatedControl
1928
{

src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Avalonia.Controls.Primitives;
1+
using Avalonia.Controls.Metadata;
2+
using Avalonia.Controls.Primitives;
23
using Avalonia.Controls.Shapes;
34
using Avalonia.Input;
45
using Avalonia.Interactivity;
@@ -12,6 +13,23 @@ namespace Avalonia.Controls
1213
/// Defines the presenter used for selecting a date for a
1314
/// <see cref="DatePicker"/>
1415
/// </summary>
16+
[TemplatePart("AcceptButton", typeof(Button))]
17+
[TemplatePart("DayDownButton", typeof(RepeatButton))]
18+
[TemplatePart("DayHost", typeof(Panel))]
19+
[TemplatePart("DaySelector", typeof(DateTimePickerPanel))]
20+
[TemplatePart("DayUpButton", typeof(RepeatButton))]
21+
[TemplatePart("DismissButton", typeof(Button))]
22+
[TemplatePart("FirstSpacer", typeof(Rectangle))]
23+
[TemplatePart("MonthDownButton", typeof(RepeatButton))]
24+
[TemplatePart("MonthHost", typeof(Panel))]
25+
[TemplatePart("MonthSelector", typeof(DateTimePickerPanel))]
26+
[TemplatePart("MonthUpButton", typeof(RepeatButton))]
27+
[TemplatePart("PickerContainer", typeof(Grid))]
28+
[TemplatePart("SecondSpacer", typeof(Rectangle))]
29+
[TemplatePart("YearDownButton", typeof(RepeatButton))]
30+
[TemplatePart("YearHost", typeof(Panel))]
31+
[TemplatePart("YearSelector", typeof(DateTimePickerPanel))]
32+
[TemplatePart("YearUpButton", typeof(RepeatButton))]
1533
public class DatePickerPresenter : PickerPresenterBase
1634
{
1735
/// <summary>

src/Avalonia.Controls/DateTimePickers/TimePicker.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@ namespace Avalonia.Controls
1212
/// <summary>
1313
/// A control to allow the user to select a time.
1414
/// </summary>
15+
[TemplatePart("FirstColumnDivider", typeof(Rectangle))]
16+
[TemplatePart("FirstPickerHost", typeof(Border))]
17+
[TemplatePart("FlyoutButton", typeof(Button))]
18+
[TemplatePart("FlyoutButtonContentGrid", typeof(Grid))]
19+
[TemplatePart("HourTextBlock", typeof(TextBlock))]
20+
[TemplatePart("MinuteTextBlock", typeof(TextBlock))]
21+
[TemplatePart("PeriodTextBlock", typeof(TextBlock))]
22+
[TemplatePart("PickerPresenter", typeof(TimePickerPresenter))]
23+
[TemplatePart("Popup", typeof(Popup))]
24+
[TemplatePart("SecondColumnDivider", typeof(Rectangle))]
25+
[TemplatePart("SecondPickerHost", typeof(Border))]
26+
[TemplatePart("ThirdPickerHost", typeof(Border))]
1527
[PseudoClasses(":hasnotime")]
1628
public class TimePicker : TemplatedControl
1729
{

src/Avalonia.Controls/DateTimePickers/TimePickerPresenter.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Avalonia.Controls.Primitives;
1+
using Avalonia.Controls.Metadata;
2+
using Avalonia.Controls.Primitives;
23
using Avalonia.Controls.Shapes;
34
using Avalonia.Input;
45
using Avalonia.Interactivity;
@@ -10,6 +11,20 @@ namespace Avalonia.Controls
1011
/// Defines the presenter used for selecting a time. Intended for use with
1112
/// <see cref="TimePicker"/> but can be used independently
1213
/// </summary>
14+
[TemplatePart("AcceptButton", typeof(Button))]
15+
[TemplatePart("DismissButton", typeof(Button))]
16+
[TemplatePart("HourDownButton", typeof(RepeatButton))]
17+
[TemplatePart("HourSelector", typeof(DateTimePickerPanel))]
18+
[TemplatePart("HourUpButton", typeof(RepeatButton))]
19+
[TemplatePart("MinuteDownButton", typeof(RepeatButton))]
20+
[TemplatePart("MinuteSelector", typeof(DateTimePickerPanel))]
21+
[TemplatePart("MinuteUpButton", typeof(RepeatButton))]
22+
[TemplatePart("PeriodDownButton", typeof(RepeatButton))]
23+
[TemplatePart("PeriodHost", typeof(Panel))]
24+
[TemplatePart("PeriodSelector", typeof(DateTimePickerPanel))]
25+
[TemplatePart("PeriodUpButton", typeof(RepeatButton))]
26+
[TemplatePart("PickerContainer", typeof(Grid))]
27+
[TemplatePart("SecondSpacer", typeof(Rectangle))]
1328
public class TimePickerPresenter : PickerPresenterBase
1429
{
1530
/// <summary>

src/Avalonia.Controls/ListBox.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections;
22
using Avalonia.Controls.Generators;
3+
using Avalonia.Controls.Metadata;
34
using Avalonia.Controls.Presenters;
45
using Avalonia.Controls.Primitives;
56
using Avalonia.Controls.Selection;
@@ -12,6 +13,7 @@ namespace Avalonia.Controls
1213
/// <summary>
1314
/// An <see cref="ItemsControl"/> in which individual items can be selected.
1415
/// </summary>
16+
[TemplatePart("PART_ScrollViewer", typeof(IScrollable))]
1517
public class ListBox : SelectingItemsControl
1618
{
1719
/// <summary>

src/Avalonia.Controls/MenuItem.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace Avalonia.Controls
2121
/// <summary>
2222
/// A menu item control.
2323
/// </summary>
24+
[TemplatePart("PART_Popup", typeof(Popup))]
2425
[PseudoClasses(":separator", ":icon", ":open", ":pressed", ":selected")]
2526
public class MenuItem : HeaderedSelectingItemsControl, IMenuItem, ISelectable, ICommandSource
2627
{

src/Avalonia.Controls/Notifications/WindowNotificationManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace Avalonia.Controls.Notifications
1414
/// <summary>
1515
/// An <see cref="INotificationManager"/> that displays notifications in a <see cref="Window"/>.
1616
/// </summary>
17+
[TemplatePart("PART_Items", typeof(Panel))]
1718
[PseudoClasses(":topleft", ":topright", ":bottomleft", ":bottomright")]
1819
public class WindowNotificationManager : TemplatedControl, IManagedNotificationManager, ICustomSimpleHitTest
1920
{

0 commit comments

Comments
 (0)