简体   繁体   English

WPF 方法绑定到 get() 和 set(value) 而不是属性

[英]WPF Method binding to get() and set(value) instead of properties

Is there any way to use binding which directly interacts with methods to get a value and set its value?有没有办法使用直接与方法交互的绑定来获取值并设置其值?

I have a class which has methods instead of properties我有一个 class,它有方法而不是属性

public class Foo
        {
            public object GetProp1()
            {
                //some logic
                return someObject;
            }
            public object GetProp2()
            {
                //some logic
                return someObject;
            }

            public object SetProp1(object someObject)
            {
                //some logic               
            }

            public object SetProp2(object someObject)
            {
                //some logic
            }
        }

To achieve data binding, I'm declaring properties for each function and calling model's method为了实现数据绑定,我为每个 function 声明属性并调用模型的方法

public class FooViewModel
        {
            Foo foo = new Foo();
            public object Prop1
            {
                get => foo.GetProp1();
                set => foo.SetProp1(value);
            }
            public object Prop2
            {
                get => foo.GetProp2();
                set => foo.SetProp2(value);
            }
        }

Problem is if I have 50 methods, in Foo, I need to create approx 50 properties in ViewModel.问题是如果我有 50 个方法,在 Foo 中,我需要在 ViewModel 中创建大约 50 个属性。 Is there any other way to eliminate properties in ViewModel just to bind with View?有没有其他方法可以消除 ViewModel 中的属性只是为了与 View 绑定?

Something like this: Textbox will set its value and Label will display像这样:文本框将设置它的值并显示 Label

<TextBox Text="{MethodBinding MethodName=foo.SetProp1}"/> 
<Label Content="{MethodBinding MethodName=foo.GetProp1}"/> 

You can technically manage to bind to methods if you really put your mind to it but I don't think that's a very helpful answer.如果您真的下定决心,您可以在技术上设法绑定到方法,但我认为这不是一个很有帮助的答案。

In any commercial team I've worked in, doing this would see your MR/PR rejected.在我工作过的任何商业团队中,这样做都会导致您的 MR/PR 被拒绝。 It is widely considered bad practice.它被广泛认为是不好的做法。

What I would recommend is make those properties regular properties raising property changed.我建议的是让这些属性改变常规属性。 Get your data for them in async tasks.在异步任务中为他们获取数据。

If you define an interface you can then give all your Getting-Data Tasks the same name and generically invoke them on any viewmodel you instantiate.如果您定义了一个接口,那么您可以为所有的获取数据任务赋予相同的名称,并在您实例化的任何视图模型上通用地调用它们。

In some real world code I have, I call this Task Initiate.在我拥有的一些真实代码中,我称此为任务启动。

interface IInitiatedViewModel
{
    Task Initiate();
}

Here's one such task ( slightly simplified ) out one of my viewmodels:这是我的一个视图模型中的一项这样的任务(稍微简化):

    public async Task Initiate()
    {
        DateFrom = LastApril();
        Transactions = await repository.GetFlattenedTransactionsAsync(DateFrom, DateTo);
    }

Transactions is a public property a Datagrid is bound to. Transactions 是 Datagrid 绑定到的公共属性。

Process is therefore to instantiate my ViewTransactionsViewModel.因此,过程是实例化我的 ViewTransactionsViewModel。 It comes out a DI container but let's not digress too far.它是一个 DI 容器,但我们不要离题太远。

I can present that viewmodel to the UI and it is templated out into a View.我可以将该视图模型呈现给 UI,并将其模板化为视图。

It has no data initially.它最初没有数据。

Then await Initiate.然后等待启动。

That sets my properties with data.用数据设置我的属性。

In more complicated scenarios, Initiate could start multiple threads with Tasks.在更复杂的场景中,Initiate 可以用 Tasks 启动多个线程。 Arranging data might be quite expensive so a Task (or many ) could be started on another thread.安排数据可能非常昂贵,因此可以在另一个线程上启动一个(或多个)任务。

A common variation is to have a base viewmodel which exposes an IsBusy bool.一个常见的变体是有一个基础视图模型,它公开一个 IsBusy 布尔值。 That is used to flag commands and drive a busy spinner.它用于标记命令并驱动繁忙的微调器。 That would initially be true.这最初是正确的。 Your view would render with a spinner.您的视图将使用微调器呈现。 The last line of Initiate would be to set IsBusy false. Initiate 的最后一行是将 IsBusy 设置为 false。 The spinner would disappear and the date would be rendered.微调器将消失,日期将被呈现。

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

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