Binding
をResource
として定義し、それを別のControls
プロパティで再利用できますか?
例:
製本:
<Window.Resources>
<Binding x:Key="MyBinding" Path="MyProperty" Mode="TwoWay" />
</Window.Resources>
XAMLでの再利用:
<TextBox Text="{StaticResource MyBinding}" />
上記のようにBinding
を宣言した後、エラーが発生しました。
「名前 'InitializeComponent'は現在のコンテキストに存在しません」
同じBinding
を異なるコンテキストで再利用する方法はありますか?
あなたの質問に対する直接の答えは、「はい、バインディングをリソースとして定義できます」です。ここでの問題は、それをどのように利用するかということです。 1つの可能性は、リソースからバインディングをプルして適用する拡張クラスを作成することです。
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
}
}
使用例:
<Window.Resources>
<ResourceDictionary>
<Binding x:Key="MyBinding" Path="MyProperty" Mode="TwoWay" />
</ResourceDictionary>
</Window.Resources>
(...)
<TextBox Text="{ns:BindingResource MyBinding}" />
このソリューションはで使用できますかMultiBinding
?
はい、できます:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="First: {0}, Second: {1}">
<Binding Path="SomeProperty" />
<ns:BindingResource ResourceKey="MyBinding" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
ただし、これには1つの欠点があります。すべてが実行時に機能しますが、XAML Designerは、BindingResourceExtension
がMultiBinding.Bindings
コレクションに入れる適切なタイプ。しかし、ありがたいことに、簡単な解決策があります。代わりにStaticResourceExtension
を使用してください!したがって、これは実行時に機能的に同等ですが、設計者によって受け入れられます。
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="First: {0}, Second: {1}">
<Binding Path="SomeProperty" />
<StaticResource ResourceKey="MyBinding" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
これがあなたが望むことを正確に行わないための2つの方法です:
1。カスタムマークアップ拡張機能の使用
短くするために、すべてのnullcheckなどをスキップしました。
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。PropertyPathをリソースにする
あなたのニーズに十分かもしれないし、そうでないかもしれません。
<Window.Resources>
<PropertyPath x:Key="MyPropertyPath">MyProperty</PropertyPath>
</Window.Resources>
...
<TextBox Text="{Binding Path={StaticResource MyPropertyPath}}" />