英文:
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:
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
Control
s,UserControl
s, andPage
s?
Conclusion
Thus:
How do I decide when to expose properties on my UserControl
s 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:
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
Control
s,UserControl
s, andPage
s?
Conclusion
Thus:
How do I decide when to expose properties on my UserControl
s or when to bind them directly to ViewModels?
答案1
得分: 2
使用 DependencyProperties
来自定义控件(Custom Controls)和用户控件(UserControls),并使用 ViewModels 用于页面(Pages)。
注意
- 如果您在控件中只公开一个 ViewModel,将很难重用您的控件与其他模型。
- ViewModel 就像一个在您的 View 和 Models 之间工作的适配器。它可能有一个简单的逻辑,但尽量保持它尽可能简单。
- 在代码后台中包含与UI相关的代码,如
FilePickerDialogs
或VisualState
更改是可以的。
英文:
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
orVisualState
changes in your code-behind.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论