Ответ 1
Нет встроенного механизма для этого. Что-то вроде PostSharp, вероятно, сможет добавить что-то подобное для вас (или Mark Gravell HyperDescriptor, если вы просто заинтересованы в том, чтобы сделать эту привязку к базе данных).
Есть ли способ использовать INotifyPropertyChanged
с авто-свойствами? Может быть, атрибут или что-то другое, не очевидное для меня.
public string Demo{
get;set;
}
Для меня авто-свойства были бы чрезвычайно практичными, но почти всегда мне нужно поднять PropertyChanged
-event, если значение свойства было изменено и без механизма для этого, авто-свойства бесполезны для меня.
Нет встроенного механизма для этого. Что-то вроде PostSharp, вероятно, сможет добавить что-то подобное для вас (или Mark Gravell HyperDescriptor, если вы просто заинтересованы в том, чтобы сделать эту привязку к базе данных).
Это то, что вам нужно было бы закодировать самостоятельно. Самое близкое, что вы могли бы получить, было бы чем-то вроде этой реализации в Code Project, который использует настраиваемый атрибут и аспект ориентированные методы, чтобы дать этот синтаксис:
[NotifyPropertyChanged]
public class AutoWiredSource
{
public double MyProperty { get; set; }
}
Кто-то когда-то предлагал в Microsoft Connect изменение спецификации С# реализовать это:
class Person : INotifyPropertyChanged
{
// "notify" is a context keyword, same as "get" and "set"
public string Name { get; set; notify; }
}
В .NET 4.5 и выше он может быть несколько короче:
private int unitsInStock;
public int UnitsInStock
{
get { return unitsInStock; }
set { SetProperty(ref unitsInStock, value);}
}
INotifyPropertyChanged
и DependencyProperties, безусловно, сделали свойства намного менее забавными. Лучшее решение, которое я нашел, - хорошие фрагменты. Например, те, которые входят в Silverlight contrib project
Я сначала пробовал использовать другие способы:
Эти методы работают, однако мне все равно пришлось мутить методы доступа всех свойств в модели или использовать объект dynamic
, который убивает ваше автозаполнение при кодировании. Также стоит упомянуть, что WinForms не поддерживают привязку к динамическим объектам, к сожалению.
В конце концов я наткнулся на ReactiveUI.Fody. Это простое в использовании решение с использованием Fody и ReactiveUI. Я успешно использовал это в своем проекте WPF.
Он соткает требуемый код шаблона RaisePropertyChanges
и ObservableAsPropertyHelper
во время компиляции.
https://github.com/kswoll/ReactiveUI.Fody
Я установил следующие пакеты в свой проект с помощью NuGet:
<packages>
<package id="Fody" version="2.0.7" targetFramework="net452" developmentDependency="true" />
<package id="reactiveui" version="7.4.0" targetFramework="net452" />
<package id="ReactiveUI.Fody" version="2.2.11" targetFramework="net452" />
<package id="reactiveui-core" version="7.4.0" targetFramework="net452" />
<package id="Rx-Core" version="2.2.5" targetFramework="net452" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net452" />
<package id="Rx-Linq" version="2.2.5" targetFramework="net452" />
<package id="Rx-Main" version="2.2.5" targetFramework="net452" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net452" />
<package id="Rx-XAML" version="2.2.5" targetFramework="net452" />
<package id="Splat" version="1.6.0" targetFramework="net452" />
</packages>
Вам нужно создать файл FodyWeavers.xml на верхнем уровне вашего проекта, чтобы он выглядел следующим образом:
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<ReactiveUI/>
</Weavers>
Вы просто устанавливаете классы Model для наследования ReactiveObject
и добавляете
[Reactive]
выше любого свойства, которое вы хотите уведомить об изменениях.
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace name.domain.some{
class SomeClass : ReactiveObject {
[Reactive]
public string SomeProperty { get; set; }
}
}
Работа выполнена! Перестройте свой проект и проверьте окно вывода в Visual Studio. Вы должны увидеть некоторые строки, выводимые из Fody, поскольку он обрабатывает ваши аннотированные классы моделей и вводит соответствующий шаблонный код. Он должен выглядеть примерно так:
Более полезную информацию можно найти здесь.