代码之家  ›  专栏  ›  技术社区  ›  Jose

获取WPF绑定的值

  •  5
  • Jose  · 技术社区  · 16 年前

    好吧,我不想在我的MVVM视图模型中有一堆icommands,所以我决定为wpf创建一个markupextension,您向它提供一个字符串(方法的名称),它将返回一个执行该方法的icommand。

    下面是一个片段:

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

    它工作得很好,除非绑定失败(例如您输入错误)。

    在XAML中执行此操作时: {Binding MyPropertyName} 每当绑定失败时,都会在输出窗口中看到。它告诉你属性名,类型名等等。

    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
    

    有什么想法吗?

    2 回复  |  直到 8 年前
        1
  •  2
  •   Tim Cooper    15 年前

    嗯,嗯,我可以想出一个迂回的方法。可能有更容易/更干净的东西,但请尝试以下方法:

    1. 得到 IProvideValueTarget 通过 IServiceProvider .
    2. 使用目标信息解析 BindingExpression 对于绑定属性。
    3. 使用 DataItem 属性上 装订表达式 获取源对象。

    类似:

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

    糟透了,但应该管用。很可能有一个服务可以为您做这件事,但我找不到一个后,在msdn快速查看。

        2
  •  0
  •   Keith Pinson sumit vedi    13 年前

    它不是绑定,对于命令,您不需要绑定,因为命令对象具有 CanExecuteChanged 事件。

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

    确保 ConverTOICommand 总是返回一些东西。是时候考虑一个空命令或其他东西了。

    推荐文章