2013-08-19 3 views
1

Я понимаю, что интересные вещи случаются с прикрепленными свойствами в datatemplates, но это очень странно.Инициализация поведения в таблицах данных

У меня есть поведение со свойством зависимостей на нем, свойство типа List<DataStatePair>

[System.Windows.Markup.ContentProperty("StateDefinitions")] 
public class MultiDataStateBehavior: StateBehaviourBase 
{ 
    public List<DataStatePair> StateDefinitions 
    { 
     get { return (List<DataStatePair>)GetValue(StateDefinitionsProperty); } 
     set { SetValue(StateDefinitionsProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for StateDefinitions. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty StateDefinitionsProperty = 
     DependencyProperty.Register("StateDefinitions", typeof(List<DataStatePair>), typeof(MultiDataStateBehavior), new PropertyMetadata(new List<DataStatePair>())); 
} 

Как вы можете видеть, я пометил его как свойство содержимого. XAML выглядит так:

<DataTemplate> 
<!-- VISUAL STATES OMITTED FOR BREVITY--> 
<Grid x:Name="grid" Background="Transparent" ContextMenu="{StaticResource ContextMenu_ToolMenu}"> 
        <i:Interaction.Behaviors> 
         <ext:MultiDataStateBehavior Binding="{Binding Type}"> 
           <ext:DataStatePair State="None" Value="{x:Null}"/> 
           <ext:DataStatePair State="Gauge" Value="{x:Static jcm:ToolType.Gauge}"/> 
           <ext:DataStatePair State="Repeater" Value="{x:Static jcm:ToolType.Gauge}"/> 
         </ext:MultiDataStateBehavior> 
        </i:Interaction.Behaviors> 
</Grid> 
</DataTemplate> 

Проблема? 3 экземпляра DataStatePair добавляются для каждого использования шаблона данных. Я использую шаблон 32 раза в своем приложении и получаю 96 экземпляров DataStatePair. Гризли! Я понимаю, как это возможно. Поведение является статичным для datatemplate, но экземпляры DataStatePair отсутствуют, и в список можно добавить список.

Если изменить свойство зависимостей на IEnumerable, то все ломается - он не будет компилироваться. Если я устанавливаю свойство явно с массивом x: Array в XAML, все работает так, как ожидалось - я получаю только 3 состояния. XAML ниже;

<i:Interaction.Behaviors> 
         <ext:MultiDataStateBehavior Binding="{Binding Type}" UseTransitionsOnLoad="True"> 
          <ext:MultiDataStateBehavior.StateDefinitions> 
           <x:Array Type="{x:Type ext:DataStatePair}"> 
            <ext:DataStatePair State="None" Value="{x:Null}"/> 
            <ext:DataStatePair State="Gauge" Value="{x:Static jcm:ToolType.Gauge}"/> 
            <ext:DataStatePair State="Repeater" Value="{x:Static jcm:ToolType.Gauge}"/> 
           </x:Array> 
          </ext:MultiDataStateBehavior.StateDefinitions> 
         </ext:MultiDataStateBehavior> 
</i:Interaction.Behaviors> 

Кто-нибудь знает, почему это и какое самое изящное решение. Я могу представить себе, что реализация Microsoft не заставит вас использовать x: Array.

EDIT: Решение x: Array разбивает дизайнер смеси.

XamlParseException: Добавить значение в коллекции типа 'System.Collections.Generic.IEnumerable (SSW.WPFExtensions.DataStatePair)' бросил исключение.

EDIT: Удаление определение в [System.Windows.Markup.ContentProperty("StateDefinitions")] атрибут работает. Я не понимаю, что происходит!

WPF, что вы делаете. WPF, STAHP

ответ

1

Потенциальное решение ... и это doozy.

Корпорация Майкрософт предоставляет руководство для создания свойств зависимостей, которые являются коллекциями here.

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

public Aquarium() : base() 
{ 
    SetValue(AquariumContentsPropertyKey, new List<FrameworkElement>()); 
} 

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

Что касается мои расчетные временные исключения. Такая же проблема ожидается с новым DataStatePair[0], который является неизменным, ужасным сообщением об ошибках.

Заключение - У кого-то из Microsoft есть хороший смешок за мой счет.