在祖先页面的UserControl.Resources中设置ViewModel

时间:2016-05-24 15:02:41

标签: xaml win-universal-app uwp uwp-xaml

假设我有一个usercontrol,如下所示。

<UserControl 
x:Class="MyApp.Controls.MyList"
xmlns:local="using:MyApp.Controls"
xmlns:viewModels="using:MyApp.ViewModels"
>
  <UserControl.Resources>
      <viewModels:CustomerViewModel x:Key="ViewModel"/>
  </UserControl.Resources>

  <UserControl.DataContext>
      <Binding Source="{StaticResource ResourceKey=ViewModel}" />
  </UserControl.DataContext>

  <UserControl.Content>
      <ListView ItemsSource={Binding ItemList} />
  </UserControl.Content>
</UserControl>

我在Page:

中使用此控件
<Page
  x:Class="MyApp.Views.CustomerPage"
  xmlns:control="using:MyApp.Controls">

    <controls:MyList />

</Page>

到目前为止一切顺利。

现在我想为其他ViewModel重用这个相同的控件。我的CustomerViewModel与我的所有viewmodel一样,都是从接口IViewModel继承的。

如果让SalesOrderViewModel使用相同的控件,我该怎么办?

我尝试了以下操作,但是在InitializeComponent()上抛出了一个XamlParseException异常:

<Page
  x:Class="MyApp.Views.CustomerPage"
  xmlns:control="using:MyApp.Controls">

    <controls:MyList>
      <controls:MyList.Resources>
        <viewModels:SalesOrderViewModel x:Key="ViewModel"/>
      </controls:MyList.Resources>
    </controls:>

</Page>

这里有什么工作方法?

2 个答案:

答案 0 :(得分:1)

Viewmodel(只是我的速度,与你的有点不同):

public class ViewModel
{
    public string Value { get; set; } = "Default";
}

用户控件:

<UserControl
    x:Class="App1.MyList"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid>
        <TextBlock Text="{Binding Value}" />
    </Grid>
</UserControl>

在页面中,为不同的DataContext s设置不同的Usercontrol

<Page.Resources>
    <local:ViewModel x:Key="ViewModel1" Value="First"/>
    <local:ViewModel x:Key="ViewModel2" Value="Second"/>
</Page.Resources>

<StackPanel>
    <local:MyList DataContext="{StaticResource ViewModel1}" />
    <local:MyList DataContext="{StaticResource ViewModel2}" />
</StackPanel>

答案 1 :(得分:0)

您可以使用数据模板。您可以使用视图模型设置数据模板的数据类型。

<UserControl.Resources>
  <DataTemplate DataType="{x:Type vm:ImageViewModel}" >
    <view:ImageView/>
  </DataTemplate>

  <DataTemplate DataType="{x:Type vm:VideoViewModel}">
    <view:VideoView/>
  </DataTemplate>
</UserControl.Resources>
<UserControl x:Class="Overlay.View.ImageView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:Example.View"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
       <Image Source="/Assets/screenshot.png"/>   
    </Grid>
</UserControl>

<UserControl x:Class="Overlay.View.VideoView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:Example.View"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <MediaElement x:Name="Player" Source="./Assets/Sample_mp4.mp4"/>
</Grid>

假设您有一个页面控件的视图模型。此视图模型可以具有IViewModel类型的属性,可以根据某些条件进行设置。您可以将此属性绑定到内容控件或内容呈现器的content属性。

<ContentControl Grid.Row="0" x:Name="ctnCtrl" Content="{Binding CurrentVm}"/>

内容控件将根据您选择的视图模型加载视图。