简体   繁体   English

获取WPF绑定的值

[英]Get the value for a WPF binding

Ok, I didn't want a bunch of ICommands in my MVVM ViewModels so I decided to create a MarkupExtension for WPF that you feed it a string(the name of the method), and it gives you back an ICommand that executes the method. 好吧,我不想在我的MVVM ViewModels中使用一堆ICommands,所以我决定为WPF创建一个MarkupExtension,它为它提供一个字符串(方法的名称),它会返回一个执行该方法的ICommand。

here's a snippet: 这是一个片段:

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

It works great, except when the binding fails(eg you mistype). 它很有效,除非绑定失败(例如你输入错误)。

When you do this in xaml: {Binding MyPropertyName} you see in the output window whenever the binding fails. 当你在xaml: {Binding MyPropertyName}执行此操作时,只要绑定失败,就会在输出窗口中看到。 and it tells you the propertyName the Type name etc. 它会告诉你propertyName的类型名称等。

The MethodConverter Class can tell you the name of the method that failed, but it can't tell you the source object type. MethodConverter类可以告诉您失败的方法的名称,但它不能告诉您源对象类型。 Because the value will be null. 因为该值将为null。

I can't figure out how to store the source object type so for the following class 我无法弄清楚如何为以下类存储源对象类型

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

and the following xaml: 和以下xaml:

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

It currently says: 它目前说:

"Could not bind to method 'MyMethod' on object

but I would like it to say: 但我想说:

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

Any ideas? 有任何想法吗?

Hmm, well I can think of a roundabout way. 嗯,我可以想到一个迂回的方式。 There may be something easier/cleaner, but try this: 可能有更简单/更清洁的东西,但试试这个:

  1. Get the IProvideValueTarget implementation via the IServiceProvider . 通过IServiceProvider获取IProvideValueTarget实现。
  2. Use the target information to resolve a BindingExpression for the bound property. 使用目标信息解析绑定属性的BindingExpression
  3. Use the DataItem property on the BindingExpression to get the source object. 使用BindingExpression上的DataItem属性来获取源对象。

Something like: 就像是:

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

Awful, but it should work. 可怕,但它应该工作。 There may well be a service that does this for you, but I couldn't find one after a quick look in MSDN. 可能有一项服务可以为您完成此操作,但在MSDN中快速浏览后我找不到一项服务。

It's not a Binding, and for commands you don't need bindings because the command objects have a CanExecuteChanged event. 它不是绑定,对于命令,您不需要绑定,因为命令对象具有CanExecuteChanged事件。

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

make sure that ConverTOICommand always returns something. 确保ConverTOICommand始终返回一些内容。 Time to think about a null command, or something. 是时候考虑一​​个null命令了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM