Ricorda che XAML è fondamentalmente solo una forma abbreviata di creazione di oggetti. Pertanto, per creare una raccolta/un elenco come valore per la proprietà DisplayFilter
allegata, è necessario racchiudere tali TabItems
all'interno di un altro tag di raccolta. Se non si desidera farlo, il che è comprensibile, è necessario inizializzare la raccolta la prima volta che si accede alla proprietà.
C'è solo un problema: il metodo getter viene saltato dal lettore XAML come ottimizzazione. È possibile evitare questo comportamento scegliendo un nome diverso per la nome argomento per la chiamata RegisterAttached
:
DependencyProperty.RegisterAttached("DisplayFilterInternal", ...)
Poi sarà chiamato il getter proprietà e si può verificare la presenza di null
. Puoi leggere ulteriori informazioni al riguardo nel numero this blog post.
Modifica: Sembra che il post del blog collegato non sia chiaro. Si cambia solo il nome della stringa passata a RegisterAttached
, non il nome dei metodi get/set statici:
public static readonly DependencyProperty DisplayFilterProperty =
DependencyProperty.RegisterAttached(
"DisplayFilterInternal",
typeof(IList),
typeof(ToolbarItem));
public static TabItemCollection GetDisplayFilter(Control item)
{ ... }
public static void SetDisplayFilter(Control item, IList value)
{ ... }
È necessario inizializzare la raccolta nel metodo GetDisplayFilter
:
public static TabItemCollection GetDisplayFilter(Control item)
{
var collection = (IList)item.GetValue(DisplayFilterProperty);
if (collection == null) {
collection = new List<object>();
item.SetValue(DisplayFilterProperty, collection);
}
return collection;
}
Sembra che tu aggiunga solo gli elementi TabItem
a quella raccolta. Quindi è possibile rendere sicura la raccolta, ma l'utilizzo di IList<T>
non funziona poiché il parser XAML non può richiamare il metodo generico Add(T)
. Collection<T>
e List<T>
implementano anche l'interfaccia non generica IList
e possono essere utilizzati in questo caso. Vorrei suggerire di creare un nuovo tipo di raccolta nel caso in cui si desidera fare alcune modifiche alla raccolta in futuro:
public class TabItemCollection : Collection<TabItem>
{
}
Se non vi interessa su come impostare la raccolta in modo esplicito in questo modo:
<ui:ToolbarItem.DisplayFilter>
<ui:TabItemCollection>
<TabItem/>
</ui:TabItemCollection>
</ui:ToolbarItem.DisplayFilter>
è possibile rimuovere il metodo SetDisplayFilter
.
In sintesi:
public class TabItemCollection : Collection<TabItem>
{
}
public class ToolbarItem
{
public static readonly DependencyProperty DisplayFilterProperty =
DependencyProperty.RegisterAttached(
"DisplayFilterInternal", // Shadow the name so the parser does not skip GetDisplayFilter
typeof(TabItemCollection),
typeof(ToolbarItem));
public static TabItemCollection GetDisplayFilter(Control item)
{
var collection = (TabItemCollection)item.GetValue(DisplayFilterProperty);
if (collection == null) {
collection = new TabItemCollection();
item.SetValue(DisplayFilterProperty, collection);
}
return collection;
}
// Optional, see above note
//public static void SetDisplayFilter(Control item, TabItemCollection value)
//{
// item.SetValue(DisplayFilterProperty, value);
//}
}
chiarito la mia risposta, HTH! – gix
Quindi ci deve essere qualcos'altro che non va perché il codice postato funziona bene. Vedi http://nopaste.org/p/adqfm5EPi per un esempio breve e completo. – gix
Sembra che tu non possa usare le risorse in questo modo. Se non si utilizzano risorse o una raccolta esplicita, sembra che funzioni. – gix