UserControls是否应该公开任意属性,还是只需ViewModel?

huangapple go评论69阅读模式
英文:

Should UserControls expose arbitrary properties or just a ViewModel?

问题

When I'm designing a cool new UserControl for WinUI 3 or UWP, should I prefer creating a control with many properties, or a control that binds directly to a ViewModel?

Example

For argument, let's take this basic card from Material UI:

UserControls是否应该公开任意属性,还是只需ViewModel?

Should I prefer:

Approach 1: expose many properties

<!-- Many properties -->
<Card
    Subtitle="Word of the Day"
    Title="Be*nev*o*lent"
    LowerSubtitle="adjective"
    Description="well meaning and kindly. 'a benevolent smile'"
    LinkText="Learn more"
    LinkUri="http://example.com" />

Approach 2: expose only ViewModel

<!-- Bind to ViewModel -->
<Card ViewModel="{x:Bind SomeViewModel}" />
runtimeclass CardViewModel: Windows.UI.Xaml.Data.INotifyPropertyChanged
{
    CardViewModel();
    String Subtitle{ get; };
    String Title{ get; };
    String LowerSubtitle{ get; };
    String Description{ get; };
    String LinkText{ get; };
    Uri LinkUri{ get; };
}

Background

In the C++/WinRT guide XAML controls; bind to a C++/WinRT property (the official intro to using C++/WinRT with XAML), you end up binding some data directly to a ViewModel:

<!-- MainPage.xaml -->
<Button Click="ClickHandler" Content="{x:Bind MainViewModel.BookSku.Title, Mode=OneWay}"/>

It even writes (in the context of comparing ViewModels to Models, emphasis added):

A view model is an abstraction of a view, and so it's bound directly to the view (the XAML markup). A data model is an abstraction of data, and it's consumed only from your view models, and not bound directly to XAML. So you can declare your data models not as runtime classes, but as C++ structs or classes. They don't need to be declared in MIDL, and you're free to use whatever inheritance hierarchy you like.

It's not clear to me if this is saying "ViewModels and View code-behind should be bound to a View, not Models" or "ViewModels should be bound to a view, not View code-behind or Models."

Furthermore, in the follow-up, XAML custom (templated) controls with C++/WinRT, you create a BgLabelControl with DependencyProperties:

<!-- MainPage.xaml -->
<local:BgLabelControl Background="Red" Label="Hello, World!"/>

But it doesn't explain when you'd want to take this approach (versus the MainPage approach) nor what is idiomatic for a UserControl (not a Control).

It's not clear to me from that documentation:

  • Whether I should prefer (Dependency)Properties or direct ViewModel binding, in general?
  • Whether this differs between Controls, UserControls, and Pages?

Conclusion

Thus:

How do I decide when to expose properties on my UserControls or when to bind them directly to ViewModels?

英文:

When I'm designing a cool new UserControl for WinUI 3 or UWP, should I prefer creating a control with many properties, or a control that binds directly to a ViewModel?

Example

For argument, let's take this basic card from Material UI:

UserControls是否应该公开任意属性,还是只需ViewModel?

Should I prefer:

Approach 1: expose many properties

&lt;!-- Many properties --&gt;
&lt;Card
    Subtitle=&quot;Word of the Day&quot;
    Title=&quot;Be*nev*o*lent&quot;
    LowerSubtitle=&quot;adjective&quot;
    Description=&quot;well meaning and kindly. &#39;a benevolent smile&#39;&quot;
    LinkText=&quot;Learn more&quot;
    LinkUri=&quot;http://example.com&quot; /&gt;

Approach 2: expose only ViewModel

&lt;!-- Bind to ViewModel --&gt;
&lt;Card ViewModel=&quot;{x:Bind SomeViewModel}&quot; /&gt;
runtimeclass CardViewModel: Windows.UI.Xaml.Data.INotifyPropertyChanged
{
    CardViewModel();
    String Subtitle{ get; };
    String Title{ get; };
    String LowerSubtitle{ get; };
    String Description{ get; };
    String LinkText{ get; };
    Uri LinkUri{ get; };
}

Background

In the C++/WinRT guide XAML controls; bind to a C++/WinRT property (the official intro to using C++/WinRT with XAML), you end up binding some data directly to a ViewModel:

&lt;!-- MainPage.xaml --&gt;
&lt;Button Click=&quot;ClickHandler&quot; Content=&quot;{x:Bind MainViewModel.BookSku.Title, Mode=OneWay}&quot;/&gt;

It even writes (in the context of comparing ViewModels to Models, emphasis added):

> A view model is an abstraction of a view, and so it's bound directly to the view (the XAML markup). A data model is an abstraction of data, and it's consumed only from your view models, and not bound directly to XAML. So you can declare your data models not as runtime classes, but as C++ structs or classes. They don't need to be declared in MIDL, and you're free to use whatever inheritance hierarchy you like.

It's not clear to me if this is saying "ViewModels and View code-behind should be bound to a View, not Models" or "ViewModels should be bound to a view, not View code-behind or Models."

Furthermore, in the follow-up, XAML custom (templated) controls with C++/WinRT, you create a BgLabelControl with DependencyProperties:

&lt;!-- MainPage.xaml --&gt;
&lt;local:BgLabelControl Background=&quot;Red&quot; Label=&quot;Hello, World!&quot;/&gt;

But it doesn't explain when you'd want to take this approach (versus the MainPage approach) nor what is idiomatic for a UserControl (not a Control).

It's not clear to me from that documentation:

  • Whether I should prefer (Dependency)Properties or direct ViewModel binding, in general?
  • Whether this differs between Controls, UserControls, and Pages?

Conclusion

Thus:

How do I decide when to expose properties on my UserControls or when to bind them directly to ViewModels?

答案1

得分: 2

使用 DependencyProperties 来自定义控件(Custom Controls)和用户控件(UserControls),并使用 ViewModels 用于页面(Pages)。

注意

  • 如果您在控件中只公开一个 ViewModel,将很难重用您的控件与其他模型。
  • ViewModel 就像一个在您的 ViewModels 之间工作的适配器。它可能有一个简单的逻辑,但尽量保持它尽可能简单。
  • 在代码后台中包含与UI相关的代码,如 FilePickerDialogsVisualState 更改是可以的。
英文:

There's no general clear rules or principles for this but let me answer to your questions.

> Whether I should prefer (Dependency)Properties or direct ViewModel binding, in general?
> Whether this differs between Controls, UserControls, and Pages?

Use DependencyProperties for (Custom) Controls and UserControls, and ViewModels for Pages.

Notes

  • If you expose only a ViewModel in your controls, it'll be very hard to reuse your controls with other models.
  • ViewModel is like an adapter that works between your View and Models. It might have a simple logic but try to make it as simple as possible.
  • It's OK to have UI related code like FilePickerDialogs or VisualState changes in your code-behind.

huangapple
  • 本文由 发表于 2023年3月21日 03:12:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75794390.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定