Не удалось исправить инициализацию AttachedProperty, установленную в XAML - PullRequest
1 голос
/ 15 июня 2019

Потратил часы на поиски ответа, но пока не удалось разбить эту головоломку.

У меня есть прикрепленное свойство, которое является ObservableCollection, и мне нужно получить UIElement узла для присоединенного свойства, чтобы правильно инициализировать эту коллекцию.

public static readonly DependencyProperty ContentProperty = DependencyProperty.RegisterAttached(
        "Content", typeof(AnimaCollection), typeof(UserControl), new FrameworkPropertyMetadata(new AnimaCollection(), BehaviorPropertyChangedCallback));
<Button Width="80" Height="30">
    <core:AnimaBehavior.Content>
        <core:AttachedAnima ToValue=".3" />
        <core:AttachedAnima ToValue="1"/>
    </animaCore:AnimaBehavior.Content>
</Button>

У меня указано BehaviorPropertyChangedCallback, но оно не запускается, когда в XAML задан сбор. Я не могу установить значение по умолчанию для свойства null, поскольку оно не будет выполнено во время выполнения при попытке добавить новые элементы в нуль. Также, если я укажу AnimaCollection в XAMl с базовыми элементами AttachedAnima и установлю значение проп по умолчанию null, обратный вызов не будет запускаться снова.

Мне нужно каким-то образом получить родительский UIElement, к которому я присоединяюсь. Таким образом, элементы коллекции могут получить ссылку на объект для работы. Любая помощь в том, как это можно сделать, будет полезна. Спасибо!

1 Ответ

1 голос
/ 15 июня 2019

Обратный вызов вызывается только при изменении свойства. При назначении новой коллекции свойству вызывается обратный вызов. При добавлении элементов в коллекцию вызывается только событие CollectionChanged коллекции (поскольку это ObservableCollection). Это означает, что BehaviorPropertyChangedCallback никогда не вызывается в вашем случае. Вы должны добавить второе прикрепленное свойство, например называется IsEnabled и добавляет к нему обратный вызов, например InitializeOnAttached(). В тот момент, когда вы устанавливаете его на элемент, такой как AnimaBehavior.IsEnabled = "True", вызывается обратный вызов InitializeOnAttached(), и вы можете получить доступ к присоединяемому элементу, приведя параметр DependencyObject.

public class AnimaBehavior
{
  public static readonly DependencyProperty ContentProperty = DependencyProperty.RegisterAttached(
        "Content", typeof(AnimaCollection), typeof(UserControl), new FrameworkPropertyMetadata(new AnimaCollection(), BehaviorPropertyChangedCallback));

  public static readonly DependencyProperty ContentProperty = DependencyProperty.RegisterAttached(
        "IsEnabled", typeof(bool), typeof(UserControl), new FrameworkPropertyMetadata(false, InitializeOnAttached));

  public static void SetContent(UIElement element, AnimaCollection value)
  {
    element.SetValue(ContentProperty, value);
  }

  public static AnimaCollection GetContent(UIElement element)
  {
    return (AnimaCollection) element.GetValue(ContentProperty);
  }

  private void InitializeOnAttached(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
    if (d is Button attachingElement)
    {
       // Use or store Button
    }


    // Or access AnimaCollection or subscribe to CollectionChanged of AnimaCollection 
    if (d is UIElement attachingElement)
    {
       // Or access AnimaCollection or subscribe to CollectionChanged of AnimaCollection 
       AnimaCollection contentCollection = AnimaBehavior.GetContent(attachingElement);
    }
  }
}

В XAML:

<Button AnimaBehavior.IsEnabled = "True">
    <core:AnimaBehavior.Content>
        <core:AttachedAnima ToValue=".3" />
        <core:AttachedAnima ToValue="1"/>
    </animaCore:AnimaBehavior.Content>
</Button>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...