2012-04-26 78 views
5

我在至極上自定義的MarkupExtension的工作,我需要從XAML非字符串參數來構建新的對象。是否可以在datacontext範圍的字段上使用非字符串參數綁定?用的MarkupExtension綁定參數

換句話說,我怎麼能這樣做?

<ListBox ItemsSource="{Binding Source={local:MyMarkupExtension {x:Type Button},IncludeMethods={Binding Source=CustomerObject.IsProblematic}}}" /> 

其中IncludeMethods=CustomerObject.IsProblematic給我這個錯誤:綁定無法在類型「TypeDescriptorExtension」的「IncludeMethods」屬性設置。 '綁定'只能在DependencyObject的DependencyProperty上設置。

任何人都可以幫助我嗎?

感謝

回答

9

A '綁定' 只能DependencyObject的一個DependencyProperty設置 - 這是真的。問題是MarkupExtension類不是從DependencyObject派生的,這就是爲什麼無法在其屬性上設置綁定的原因。

[編輯]

解決方法是使用ValueConverters。另一個解決方法是更改​​C#語言以允許多重繼承。順便說一句,在Silverlight MarkupExtension實現IMarkupExtension接口,所以我想實現它在我的自定義擴展,並推導出它DependecyObject,加入DependencyProperty那裏,集綁定到它。它不會崩潰,但綁定實際上是 ProvideValue()被調用。所以即使在Silverlight中也沒有解決方案(或者很難 - 請參閱Klaus78's answer中提供的鏈接)。在WPF中,MarkupExtension沒有實現任何接口,所以你不能綁定到它的屬性。

+0

任何人都可以建議我一個解決方法嗎? – user1351709 2012-04-26 07:37:07

+0

請看到我的編輯 – EvAlex 2012-04-26 08:02:11

+17

更改C#語言允許多重繼承不正是我所說的「解決辦法」;) – 2012-04-26 08:11:28

0

此鏈接信息約

Custom Markup Extension with bindable properties

編輯 有人讓我注意,這僅適用於Silverlight的,因爲在WPF的MarkupExtension沒有實現IMarkupExtension接口。 (謝謝EvAlex)

+0

它僅適用於Silverlight的,因爲在WPF的MarkupExtension沒有實現IMarkupExtension接口 – EvAlex 2012-04-26 08:02:00

-1

,我發現了這個問題的解決方法。
主要想法是爲需要綁定的每個參數定義附加屬性。

public class MarkupExtensionWithBindableParam : MarkupExtension 
{ 
    public BindingBase Param1 { get; set; } // its necessary to set parameter type as BindingBase to avoid exception that binding can't be used with non DependencyProperty 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget; 
     DependencyObject targetObject; 
     DependencyProperty targetProperty; 

     if (target != null && target.TargetObject is DependencyObject && target.TargetProperty is DependencyProperty) 
     { 
      targetObject = (DependencyObject)target.TargetObject; 
      targetProperty = (DependencyProperty)target.TargetProperty; 
     } 
     else 
     { 
      return this; // magic 
     } 

     // Bind the Param1 to attached property Param1BindingSinkProperty 
     BindingOperations.SetBinding(targetObject, MarkupExtensionWithBindableParam.Param1BindingSinkProperty, Param1); 

     // Now you can use Param1 

     // Param1 direct access example: 
     object param1Value = targetObject.GetValue(Param1BindingSinkProperty); 

     // Param1 use in binding example: 
     var param1InnerBinding = new Binding() { Source = targetObject, Path = new PropertyPath("(0).SomeInnerProperty", Param1BindingSinkProperty) }); // binding to Param1.SomeInnerProperty 
     return param1InnerBinding.ProvideValue(serviceProvider); // return binding to Param1.SomeInnerProperty 
    } 

    private static DependencyProperty Param1BindingSinkProperty = DependencyProperty.RegisterAttached("Param1BindingSink", typeof(object)// set the desired type of Param1 for at least runtime type safety check 
         , typeof(MarkupExtensionWithBindableParam), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits)); 
} 

用法很簡單:

<TextBlock Text={local:MarkupExtensionWithBindableParam Param1={Binding Path="SomePathToParam1"}}/> 
+0

有與*用途*例如一個問題。標記不是必須用引號括起來嗎? – OmegaMan 2016-07-22 14:50:15

+1

似乎不起作用; param1Value始終爲空 – esskar 2016-09-15 12:48:00