CommunityToolkit / CommunityToolkit/dotnet
[MVVM] `AttachedProperty`/`DirectProperty`/`StyledProperty` source generators
- Dominant language
- C#
- Stars
- 3.8k
- Forks
- 400
- PR merge metrics
- No merged PRs in 30d
Description
### Overview
Examples like these require a considerable amount of repetitive code:
```cs
public bool Foo
{
get => GetValue(FooProperty);
set => SetValue(FooProperty, value);
}
public ObservableCollection? BarsSource
{
get => GetValue(BarsSourceProperty);
set => SetValue(BarsSourceProperty, value);
}
public ICommand? BazCommand
{
get => GetValue(BazCommandProperty);
set => SetValue(BazCommandProperty, value);
}
public static readonly StyledProperty FooProperty =
AvaloniaProperty.Register(nameof(Foo));
public static readonly StyledProperty?> BarsSourceProperty =
AvaloniaProperty.Register?>(nameof(BarsSource));
public static readonly StyledProperty BazCommandProperty =
AvaloniaProperty.Register(nameof(BazCommand));
```
### API breakdown
```cs
namespace CommunityToolkit.Mvvm.ComponentModel;
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class AttachedPropertyAttribute : Attribute;
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class DirectPropertyAttribute : Attribute;
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class StyledPropertyAttribute : Attribute;
```
### Usage example
`QuxControl.cs`
```cs
public partial class QuxControl : Panel
{
[StyledProperty]
public partial bool Foo { get; set; }
[StyledProperty]
public partial ObservableCollection? BarsSource { get; set; }
[StyledProperty]
public partial ICommand? BazCommand { get; set; }
}
```
`MyProject.Views.QuxControl.g.cs`
```cs
namespace MyProject.Views
{
partial class QuxControl
{
/* ... */
public partial bool Foo
{
get => GetValue(FooProperty);
set => SetValue(FooProperty, value);
}
/* ... */
public partial ObservableCollection? BarsSource
{
get => GetValue(BarsSourceProperty);
set => SetValue(BarsSourceProperty, value);
}
/* ... */
public partial ICommand? BazCommand
{
get => GetValue(BazCommandProperty);
set => SetValue(BazCommandProperty, value);
}
/* ... */
public static readonly StyledProperty FooProperty =
AvaloniaProperty.Register(nameof(Foo));
/* ... */
public static readonly StyledProperty?> BarsSourceProperty =
AvaloniaProperty.Register?>(nameof(BarsSource));
/* ... */
public static readonly StyledProperty BazCommandProperty =
AvaloniaProperty.Register(nameof(BazCommand));
}
}
```
### Breaking change?
No
### Alternatives
There are existing packages (https://github.com/jp2masa/Avalonia.PropertyGenerator, https://github.com/lucdem/AvaSourceGenerators) that don't entirely work in the proposed way.
### Additional context
_No response_
### Help us help you
No, just wanted to propose this
Contributor guide
Assessment
This issue has not been assessed yet.