简体   繁体   English

MVVM uwp UserControl,VM为DataTemplate

[英]MVVM uwp UserControl with VM as DataTemplate

I'm trying to create an app in UWP using MVVM pattern. 我正在尝试使用MVVM模式在UWP中创建一个应用程序。 It's possible that usercontrol which is a DataTemplate for items in Listbox would have his own VM. 作为Listbox中项目的DataTemplate的usercontrol可能有自己的VM。

Here is part of MainPage.xaml 这是MainPage.xaml的一部分

 <ListBox Name="ListBox1" ItemsSource="{Binding Components}">
            <ListBox.ItemTemplate >
                <DataTemplate x:DataType="vm:ComponentUserControlViewModel"  >
                    <local:ComponentUserControl />
                </DataTemplate>
            </ListBox.ItemTemplate>
 </ListBox>

MainPageVM contains: MainPageVM包含:

public ObservableCollection<Component> Components

For now it's my UserControl 现在它是我的UserControl

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <TextBox Text="{Binding Id}" Grid.Row="0"></TextBox>
    <TextBox Text="{Binding Name}" Grid.Row="1"></TextBox>

</Grid>

VM: VM:

    public class ComponentUserControlViewModel : ViewModelBase
{
    private string _componentId;
    private string _componentName;

    public ComponentUserControlViewModel()
    {
    }

    public string Id
    {
        get { return _componentId; }
        set
        {
            SetProperty(ref _componentId, value);
        }
    }
    public string Name
    {
        get { return _componentName; }
        set
        {
            SetProperty(ref _componentName, value);
        }
    }

What I want is for eg If I change Id property in my UI the view model Id property will changed too. 我想要的是例如,如果我在我的UI中更改Id属性,视图模型Id属性也将更改。

What Kris stated is true, you need dependency properties to achieve what you want. Kris说的是真的,你需要依赖属性来实现你想要的。

In short, you can have two types of properties: the good old properties like you have in your ViewModel, Id and Name, and dependency properties. 简而言之,您可以拥有两种类型的属性:在ViewModel中具有良好的旧属性,Id和Name以及依赖项属性。 (Of course there are attached properties too, but conceptually they are the same as dependency properties.) The main difference between these two types of properties is that while both types can be targets to a data binding, only dependency properties can be the source of a data binding. (当然也有附加属性过,但概念上它们是相同的依赖特性。)这两种类型的属性之间的主要区别是,虽然这两种类型可以是目标 ,以一个数据绑定,仅依赖属性可以是数据绑定。 That's right what you need. 这就是你需要的。

So to solve your problem, we'll need a dependency property, defined in the code-behind of your control. 因此,要解决您的问题,我们需要一个依赖项属性,在您的控件的代码隐藏中定义。 Let's call this property 'Component', like Kris does it in his answer: 让我们将这个属性称为“组件”,就像Kris在他的回答中所做的那样:

public static readonly DependencyProperty ComponentProperty = DependencyProperty.Register(
    "Component",
    typeof(ComponentUserControlViewModel), 
    typeof(ComponentUserControl), 
    new PropertyMetadata(null));

public ComponentUserControlViewModel Component
{
    get { return (ComponentUserControlViewModel) GetValue(ComponentProperty); }
    set { SetValue(ComponentProperty, value); }
}

Now if you change your binding on your UserControl to these (Note the Mode=OneWay, x:Bind is OneTime by default! More about it here .): 现在,如果你将UserControl的绑定更改为这些(注意Mode = OneWay,x:Bind默认为OneTime! 这里有更多关于它的信息 。):

<TextBox Text="{x:Bind Component.Id, Mode=OneWay}" Grid.Row="0" />
<TextBox Text="{x:Bind Component.Name, Mode=OneWay}" Grid.Row="1" />

And replace your DataTemplate-s content with the one Kris supplied: 并使用提供的Kris替换您的DataTemplate内容:

<local:ComponentUserControl Component="{Binding}" />

The magic will happen and all of this will work! 魔法将会发生,所有这一切都会奏效! :) If you have any more questions on the matter, please check this official overview of dependency properties. :)如果您对此事有任何疑问,请查看依赖属性的官方概述

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

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