2010-03-29 75 views
4

確定的價值,我不想一堆個ICommand在我的MVVM的ViewModels所以我決定創建一個WPF的MarkupExtension,你給它一個字符串(方法的名字),它爲您提供執行該方法的ICommand。獲取一個WPF結合

這裏有一個片段:

public class MethodCall : MarkupExtension 
{ 
    public MethodCall(string methodName) 
    { 
    MethodName = methodName; 
    CanExecute = "Can" + methodName; 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
    Binding bin= new Binding { Converter = new MethodConverter(MethodName,CanExecute) }; 

    return bin.ProvideValue(serviceProvider); 
    } 
} 

public class MethodConverter : IValueConverter 
{ 
    string MethodName; 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
    //Convert to ICommand 
    ICommand cmd = ConvertToICommand(); 
    if (cmd == null) 
     Debug.WriteLine(string.Format("Could not bind to method 'MyMethod' on object",MethodName)); 
    return cmd;  
    } 
} 

它的偉大工程,在綁定失敗時除外(e.g你輸錯)。

當您在xaml中執行此操作時: {Binding MyPropertyName}只要綁定失敗,就會在輸出窗口中看到它。它會告訴你的propertyName的類型名稱等

的MethodConverter類可以告訴你失敗的方法的名稱,但它不能告訴你源對象類型。因爲該值將爲空。

我無法弄清楚如何存儲源對象類型所以下面的類

public class MyClass 
{ 
    public void MyMethod() 
    { 
    } 
} 

和下面的XAML代碼:

<Button Command={d:MethodCall MyMethod}>My Method</Button> 

目前,它說:

"Could not bind to method 'MyMethod' on object 

但我想它說:

"Could not bind to method 'MyMethod' on object MyClass 

任何想法?

回答

1

嗯,我可以想到一個迂迴的方式。有可能是一些比較容易/清潔劑,但試試這個:

  1. 獲得通過IServiceProviderIProvideValueTarget實施。
  2. 使用目標信息解析綁定屬性的BindingExpression
  3. 使用的BindingExpressionDataItem屬性來獲取源對象。

喜歡的東西:

var provideValueTarget = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget)); 
var bindingExpression = BindingOperations.GetBindingExpression(provideValueTarget.TargetObject, (DependencyProperty)provideValueTarget.TargetProperty); 
var source = bindingExpression.DataItem; 

可怕,但它應該工作。很可能有一種服務可以爲您做到這一點,但在MSDN中快速查看後,我找不到它。

0

這不是一個綁定,併爲命令,因爲該命令對象有CanExecuteChanged事件你不需要綁定。

public override object ProvideValue(IServiceProvider serviceProvider) 
{  
    ICommand cmd = ConvertToICommand(); 
    return cmd; 
} 

確保ConverTOICommand總是返回一些東西。現在想想一個空命令或什麼的。