Как создать XAML-подобные привязки путей в C # - PullRequest
1 голос
/ 28 апреля 2010

Конструкция XAML {Binding} очень удобна, потому что она автоматически обрабатывает все проблемы PropertyChanged. Это действительно впечатляет, когда вы указываете путь к объекту через структуры данных .NET, и все автоматически обновляется для вас.

Я хотел бы использовать то же самое в C #. Я хотел бы иметь свойство, которое получено из значения другого свойства. Пример

class Foo
{
    public Bar Bar = new Bar();
    public string ItGetter
    {
        get
        {
            return Bar.Baz.It;
        }
    }
}

class Bar
{
    public Baz Baz = new Baz();
}

class Baz
{
    public string It { get { return "You got It!"; } }
}

Если вы вызываете ItGetter для Foo, вы получаете значение It от Baz. Это работает нормально, за исключением того, что оно не аннулировано - т.е. если оно изменилось, на ItGetter не было бы уведомлений об изменениях. Кроме того, если ссылки Foo.Bar или Bar.Baz изменены, вы также не получите уведомления об изменении.

Я могу добавить соответствующий код IChangeNotify в свойствах, но у меня такой вопрос: как мне кодировать свойство ItGetter, чтобы оно вызывало событие PropertyChanged при изменении какой-либо из ссылок в пути или значение It? Я надеюсь, что мне не нужно вручную настраивать события измененных свойств для всех элементов в пути ....

Спасибо за любую помощь!

Eric

Ответы [ 2 ]

1 голос
/ 29 апреля 2010

Вот полный код, который делает то, что я искал, используя Dependency Properties, как упомянул Саймон:

// This class exists to encapsulate the INotifyPropertyChanged requirements
public class ChangeNotifyBase : DependencyObject, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}

public class Foo : ChangeNotifyBase
{
    public Foo()
    {
        Bar = new Bar();
        var binding = new Binding("Bar.Baz.It");
        binding.Source = this;
        binding.Mode = BindingMode.TwoWay;
        BindingOperations.SetBinding(this, ItGetterProperty, binding);
    }

    /// <summary>
    /// The ItGetter dependency property.
    /// </summary>
    public bool ItGetter
    {
        get { return (bool)GetValue(ItGetterProperty); }
        set { SetValue(ItGetterProperty, value); }
    }
    public static readonly DependencyProperty ItGetterProperty =
        DependencyProperty.Register("ItGetter", typeof(bool), typeof(Foo));

    // Must do the OnPropertyChanged to notify the dependency machinery of changes.
    private Bar _bar;
    public Bar Bar { get { return _bar; } set { _bar = value; OnPropertyChanged("Bar"); } }
}

public class Bar : ChangeNotifyBase
{
    public Bar()
    {
        Baz = new Baz();
    }
    private Baz _baz;
    public Baz Baz { get { return _baz; } set { _baz = value; OnPropertyChanged("Baz"); } }
}

public class Baz : ChangeNotifyBase
{
    private bool _it;
    public bool It { get { return _it; } set { _it = value; OnPropertyChanged("It"); } }
}

Если вы сейчас зарегистрируетесь для событий на ItGetter, вы получите уведомление, если какой-либо из нихвсе меняется: Baz.It Foo.Bar (т. е. изменить ссылку) Bar.Baz ""

Если для ссылки на объект (Foo.Bar или Bar.Baz) установить значение NULL, значениеItGetter изменяется на false.

1 голос
/ 28 апреля 2010

Вы можете взглянуть на свойства зависимости . Они позволяют вам определять свойства в системе свойств WPF, которые поддерживаются стеками метаданных и подробной системой разрешения значений.

Для вас важно, что они позволяют вам регистрироваться для событий, изменяющих свойства, и позволяют вам устанавливать значения в зависимости от других вещей.

Есть еще несколько хороших примеров, таких как «Демистифицирующие свойства зависимости» Джоша Смита и «Свойства зависимости» Кристиана Мозерса

Возможно, вы также захотите прочитать Обратные вызовы и проверка свойств зависимостей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...