wpf xaml wpf-controls resourcedictionary

wpf - La encuadernación como recurso



xaml wpf-controls (2)

Aquí hay dos maneras de no hacer exactamente lo que quieres:

1. Usando una extensión de marcado personalizado

Se saltan todos los nullchecks, etc. para que sea breve.

using System; using System.Windows; using System.Windows.Data; using System.Windows.Markup; public class BindingDefinition { public PropertyPath Path { get; set; } public BindingMode Mode { get; set; } } [MarkupExtensionReturnType(typeof(BindingExpression))] public class ApplyBindingDefinition : MarkupExtension { public BindingDefinition Definition { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { var binding = new Binding { Path = this.Definition.Path, Mode = this.Definition.Mode }; return binding.ProvideValue(serviceProvider); } }

<Window.Resources> <local:BindingDefinition x:Key="MyProperty" Mode="TwoWay" Path="MyProperty" /> </Window.Resources> <TextBox> <TextBox.Text> <!-- using element style here as the parser chokes on parsing nested markupextensions --> <local:ApplyBindingDefinition Definition="{StaticResource MyProperty}" /> </TextBox.Text> </TextBox>

2. Convertir el PropertyPath en un recurso

Puede o no puede ser suficiente para sus necesidades.

<Window.Resources> <PropertyPath x:Key="MyPropertyPath">MyProperty</PropertyPath> </Window.Resources> ... <TextBox Text="{Binding Path={StaticResource MyPropertyPath}}" />

¿Puedo definir un Binding como un Resource y luego reutilizarlo con diferentes propiedades de Controls ?

Ejemplo:

Unión:

<Window.Resources> <Binding x:Key="MyBinding" Path="MyProperty" Mode="TwoWay" /> </Window.Resources>

Reutilizar en XAML:

<TextBox Text="{StaticResource MyBinding}" />

Después de declarar el Binding como arriba, recibí el error:

"El nombre ''InitializeComponent'' no existe en el contexto actual"

¿Hay alguna forma de reutilizar el mismo Binding en diferentes contextos?


La respuesta directa a su pregunta es "sí, puede definir un enlace como un recurso". El problema aquí es, ¿cómo hacer uso de él? Una posibilidad es crear una clase de extensión que extraiga el enlace de los recursos y la aplique:

public class BindingResourceExtension : StaticResourceExtension { public BindingResourceExtension() : base() { } public BindingResourceExtension(object resourceKey) : base(resourceKey) { } public override object ProvideValue(IServiceProvider serviceProvider) { var binding = base.ProvideValue(serviceProvider) as BindingBase; if (binding != null) return binding.ProvideValue(serviceProvider); else return null; //or throw an exception } }

Ejemplo de uso:

<Window.Resources> <ResourceDictionary> <Binding x:Key="MyBinding" Path="MyProperty" Mode="TwoWay" /> </ResourceDictionary> </Window.Resources> (...) <TextBox Text="{ns:BindingResource MyBinding}" />

¿Se puede utilizar esta solución en MultiBinding ?

Sí puede:

<TextBlock> <TextBlock.Text> <MultiBinding StringFormat="First: {0}, Second: {1}"> <Binding Path="SomeProperty" /> <ns:BindingResource ResourceKey="MyBinding" /> </MultiBinding> </TextBlock.Text> </TextBlock>

Sin embargo, hay un inconveniente de esto: aunque todo funcionará en tiempo de ejecución, el Diseñador XAML se quejará de que BindingResourceExtension no es del tipo adecuado para MultiBinding.Bindings en la colección MultiBinding.Bindings . Pero, afortunadamente, existe una solución rápida: ¡simplemente use StaticResourceExtension en StaticResourceExtension lugar! Así que esto, aunque es funcionalmente equivalente en tiempo de ejecución, será aceptado por el diseñador:

<TextBlock> <TextBlock.Text> <MultiBinding StringFormat="First: {0}, Second: {1}"> <Binding Path="SomeProperty" /> <StaticResource ResourceKey="MyBinding" /> </MultiBinding> </TextBlock.Text> </TextBlock>