wpf attached-properties

wpf - Propiedad adjunta de tipo lista



attached-properties (1)

Recuerde que XAML es básicamente una forma abreviada de creación de objetos. Entonces, para crear una colección / lista como el valor de la propiedad DisplayFilter adjunta, tendría que incluir esos TabItems dentro de otra etiqueta de colección. Si no desea hacer eso, lo cual es comprensible, debe inicializar la colección la primera vez que se accede a la propiedad.

Hay un solo problema con esto: el lector XAML omite el método getter como una optimización. Puede evitar este comportamiento eligiendo un nombre diferente para el argumento de nombre a la llamada RegisterAttached :

DependencyProperty.RegisterAttached("DisplayFilterInternal", ...)

A continuación, se llamará al captador de propiedades y puede comprobar si hay null . Puedes leer más sobre eso en esta publicación de blog .

Edición: Parece que la publicación del blog vinculado no es tan clara. Solo cambia el nombre de la cadena pasada a RegisterAttached , no el nombre de los métodos estáticos get / set:

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) { ... }

Tienes que inicializar la colección en el método 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; }

Parece que solo TabItem elementos de TabItem a esa colección. Luego puede hacer que la colección sea segura, pero el uso de IList<T> no funciona, ya que el analizador XAML no puede invocar el método genérico Add(T) . Collection<T> y List<T> también implementan la interfaz IList no genérica y se pueden usar en este caso. Le sugeriría crear un nuevo tipo de colección en caso de que quiera hacer algunos cambios en la colección en el futuro:

public class TabItemCollection : Collection<TabItem> { }

Si no te importa configurar la colección explícitamente de esta manera:

<ui:ToolbarItem.DisplayFilter> <ui:TabItemCollection> <TabItem/> </ui:TabItemCollection> </ui:ToolbarItem.DisplayFilter>

puede eliminar el método SetDisplayFilter .

Para resumir:

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); //} }

Quiero crear una propiedad adjunta que pueda usarse con esta sintaxis:

<Button> <Image .../> <ui:ToolbarItem.DisplayFilter> <TabItem .../> <TabItem .../> <TabItem .../> </ui:ToolbarItem.DisplayFilter> </Button>

Este es mi intento de hacerlo:

public class ToolbarItem { /// <summary> /// Identifies the DisplayFilter attached property. /// </summary> public static readonly DependencyProperty DisplayFilterProperty = DependencyProperty.RegisterAttached( "DisplayFilter", typeof( IList ), typeof( ToolbarItem ) ); public static IList GetDisplayFilter( Control item ) { return (IList)item.GetValue( DisplayFilterProperty ); } public static void SetDisplayFilter( Control item, IList value ) { item.SetValue( DisplayFilterProperty, value ); } }

Sin embargo, esto está causando una excepción en el tiempo de análisis: System.ArgumentException: TabItem no es un valor válido para la propiedad ''DisplayFilter''. Entonces, ¿cómo configuro mi propiedad adjunta para poder usar la sintaxis XAML deseada?