2014-12-13 3 views
1

MainPage.xamlWindows Phone 8,1 MVVM Установка ViewModel зрения

<phone:PhoneApplicationPage 
    x:Class="MyApp.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
    SupportedOrientations="Portrait" Orientation="Portrait" 
    shell:SystemTray.IsVisible="True" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:viewModels="clr-namespace:MyApp.ViewModels" 
    xmlns:views="clr-namespace:MyApp.Views" 
    mc:Ignorable="d" 
    d:DataContext="{d:DesignInstance Type=viewModels:MainViewModel}"> 

    <!--FontFamily="{StaticResource PhoneFontFamilyNormal}" 
    FontSize="{StaticResource PhoneFontSizeNormal}" 
    Foreground="{StaticResource PhoneForegroundBrush}"--> 

    <!--LayoutRoot is the root grid where all page content is placed--> 
    <Grid x:Name="LayoutRoot" Background="Transparent"> 



     <!--Pivot Control--> 
     <phone:Pivot Title="MyApp"> 
      <!--Pivot item one--> 
      <phone:PivotItem Header="Main"> 
       <Grid> 

       </Grid> 
      </phone:PivotItem> 

      <!--Pivot item two--> 
      <phone:PivotItem Header="Counter"> 
       <views:CounterView /> 
      </phone:PivotItem> 
     </phone:Pivot> 
    </Grid> 

</phone:PhoneApplicationPage> 

CounterView.XAML

<UserControl x:Class="MyApp.Views.CounterView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     FontFamily="{StaticResource PhoneFontFamilyNormal}" 
     FontSize="{StaticResource PhoneFontSizeNormal}" 
     Foreground="{StaticResource PhoneForegroundBrush}" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:viewModels="clr-namespace:MyApp.ViewModels" 
     mc:Ignorable="d" 
     d:DesignHeight="480" d:DesignWidth="480"   
     d:DataContext="{d:DesignInstance Type=viewModels:CounterViewModel}"> 


     <Grid x:Name="LayoutRoot" Background="Blue" > 
      <TextBlock Text="{Binding LightSensorInfo}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="75,137,0,316"/> 
     </Grid> 
    </UserControl> 

Ошибка:

System.Windows.Data Error: BindingExpression path error: 'LightSensorInfo' property not found on 'MyApp.ViewModels.MainViewModel' 'MyApp.ViewModels.MainViewModel' (HashCode=62333418). BindingExpression: Path='LightSensorInfo' DataItem='MyApp.ViewModels.MainViewModel' (HashCode=62333418); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String').. 

Почему он ll Приложение пытается заглянуть в MainViewModel вместо CounterViewModel, который я установил в CounterView, DataContext?

В WPF, ResourceDictionary я использовал, чтобы установить это тоже:

<DataTemplate DataType="viewModels:CounterViewModel"> 
    <views:CounterView/> 
</DataTemplate> 

Но похоже, WindowsPhone не может найти DataType недвижимость, так что я закомментировать эту часть.

Что мне не хватает? Есть идеи?

+0

Вы пытаетесь создать собственную модель просмотра пользовательского контроля? – RenDishen

+1

Возможно, потому, что это контекст данных времени разработки, а не фактический контекст данных? – John

+0

В моих стилях приложения WP 8.1 без 'x: Key' игнорируются, если они помещаются в файл словаря внешних ресурсов. Попробуйте перенести DataTemplate прямо в '' – opewix

ответ

1

Hoooah! Решение найдено!

CounterView.XAML

Неправильно:

d:DataContext="{d:DesignInstance Type=viewModels:CounterViewModel}" 

Правильно:

<UserControl.DataContext> 
    <viewModels:CounterViewModel/> 
</UserControl.DataContext> 

Финал:

<UserControl x:Class="MyApp.Views.CounterView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}" 
    FontSize="{StaticResource PhoneFontSizeNormal}" 
    Foreground="{StaticResource PhoneForegroundBrush}" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:viewModels="clr-namespace:MyApp.ViewModels" 
    mc:Ignorable="d" 
    d:DesignHeight="480" d:DesignWidth="480"> 

    <UserControl.DataContext> 
     <viewModels:CounterViewModel/> 
    </UserControl.DataContext> 


    <Grid x:Name="LayoutRoot" Background="Blue" > 
     <TextBlock Text="{Binding LightSensorInfo}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="75,137,0,316"/> 
    </Grid> 
</UserControl> 

Работает как Шарм! Это единственное изменение, которое я сделал - не нужно было ничего делать.

+1

Ваш ответ действительно правильный, но ваш «неправильный» XAML подходит для проектирования вашего UserControl, так что Intellisense может найти ваши свойства ViewModel. Вы можете включить оба в ваш XAML. –

0

http://blog.jerrynixon.com/2013/07/solved-two-way-binding-inside-user.html

Похоже, ответ в этом блоге. Пока не проверено, но это звучит логично:

Please note: the data context property of the user control inherits from the parent. A DataTemplate might like this. But user controls don’t anticipate a data context type. Instead, they want properties explicitly set. And we want to bind those properties.

Не стесняйтесь обновлять меня. :)