2014-11-23 59 views
0

我正尝试构建一个使用集线器作为用户界面并在保存日记后更新用户界面的日记应用程序。我已经实现了INotifyPropertyChanged,但它不起作用。我希望保存后添加的项目立即显示在集线器上。Windows Phone 8.1集线器部分更新项目(INotifyPropertyChanged)

public class SampleDataGroup : INotifyPropertyChanged 
{ 

    public SampleDataGroup() 
    { 
     UniqueId = string.Empty; 
     Title = string.Empty; 
     Subtitle = string.Empty; 
     Description = string.Empty; 
     ImagePath = string.Empty; 
     Items = new ObservableCollection<DiaryData>(); 
    } 

    public string UniqueId { get; private set; } 
    public string Title { get; private set; } 
    public string Subtitle { get; private set; } 
    public string Description { get; private set; } 
    public string ImagePath { get; private set; } 
    private ObservableCollection<DiaryData> _items; 
    public ObservableCollection<DiaryData> Items { get{return _items;} private set 
    { 
     OnPropertyChanged("Items"); 
     _items = value; 

    } } 

    public override string ToString() 
    { 
     if (this.Title != null) 
     { 
      return this.Title; 
     } 
     else 
     { 
      System.Diagnostics.Debug.WriteLine("this is null at tostring"); 
      return null; 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    public void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

} 

public sealed class SampleDataSource : INotifyPropertyChanged 
{ 
    private static SampleDataSource _sampleDataSource = new SampleDataSource(); 

    private ObservableCollection<SampleDataGroup> _groups = new ObservableCollection<SampleDataGroup>(); 
    public ObservableCollection<SampleDataGroup> Groups 
    { 
     get { return this._groups; } 
     set { } 
    } 

    public static async Task<IEnumerable<SampleDataGroup>> GetGroupsAsync() 
    { 
     await _sampleDataSource.GetSampleDataAsync(); 

     return _sampleDataSource.Groups; 
    } 

    public static async Task<SampleDataGroup> GetGroupAsync(string uniqueId) 
    { 
     System.Diagnostics.Debug.WriteLine("GetGroupAsync is entered phase 1"); 
     await _sampleDataSource.GetSampleDataAsync(); 
     // Simple linear search is acceptable for small data sets 
     System.Diagnostics.Debug.WriteLine("GetGroupAsync is entered phase 2"); 
     var matches = _sampleDataSource.Groups.Where((group) => group.UniqueId.Equals(uniqueId)); 

     if (matches.Count() == 1) return matches.First(); 
     return null; 
    } 

    public static async Task<DiaryData> GetItemAsync(string uniqueId) 
    { 
     await _sampleDataSource.GetSampleDataAsync(); 
     System.Diagnostics.Debug.WriteLine("GetItemAsync is entered"); 
     // Simple linear search is acceptable for small data sets 
     var matches = _sampleDataSource.Groups.SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId)); 
     if (matches.Count() == 1) return matches.First(); 
     else return null; 
    } 

    private async Task GetSampleDataAsync() 
    { 
     System.Diagnostics.Debug.WriteLine("GetSampleDataAsync is entered"); 
     //if (this._groups.Count != 0)return; 

     Uri dataUri = new Uri("ms-appdata:///local/data.json"); 

     StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(dataUri); 
     string jsonText = await FileIO.ReadTextAsync(file); 
     JsonArray jsonArray = JsonArray.Parse(jsonText); 

     SampleDataGroup group = new SampleDataGroup(); 
      foreach (JsonValue itemValue in jsonArray) 
      { 
       JsonObject itemObject = itemValue.GetObject(); 
       group.Items.Add(new DiaryData(itemObject["Title"].GetString(), 
                itemObject["Content"].GetString(), 
                itemObject["Coordinate"].GetString(), 
                itemObject["UniqueId"].GetString(), 
                itemObject["ImagePath"].GetString(), 
                itemObject["VideoPath"].GetString())); 
       System.Diagnostics.Debug.WriteLine(itemObject["Title"].GetString()); 
      } 
      this.Groups.Add(group); 
      System.Diagnostics.Debug.WriteLine("GetSampleDataAsync is finished"); 
     } 

    //} 



    public event PropertyChangedEventHandler PropertyChanged; 

} 

这里是我的XAML文件


<Page 
x:Class="DiaryAppHub.HubPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="using:DiaryAppHub" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:data="using:DiaryAppHub.Data" 
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}" 
d:DataContext="{Binding Source={d:DesignData Source=/DataModel/SampleData.json, Type=data:data.json}}" 
mc:Ignorable="d"> 

<Page.Resources> 
    <DataTemplate x:Key="HubSectionHeaderTemplate"> 
     <TextBlock Margin="0,0,0,-9.5" Text="{Binding}"/> 
    </DataTemplate> 

    <!-- Grid-appropriate item template as seen in section 2 --> 
    <DataTemplate x:Key="Standard200x180TileItemTemplate"> 
     <Grid Margin="0,0,9.5,9.5" Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}"> 
      <Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}" Height="138.5" Width="138.5"/> 
      <TextBlock Text="{Binding Title}" VerticalAlignment="Bottom" Margin="9.5,0,0,6.5" Style="{ThemeResource BaseTextBlockStyle}"/> 
     </Grid> 
    </DataTemplate> 

    <DataTemplate x:Key="StandardTripleLineItemTemplate"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="*"/> 
      </Grid.ColumnDefinitions> 

      <Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,9.5,0,0" Grid.Column="0" HorizontalAlignment="Left"> 
       <Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}" Height="79" Width="79"/> 
      </Border> 
      <StackPanel Grid.Column="1" Margin="14.5,0,0,0"> 
       <TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}"/> 
       <TextBlock Text="{Binding Description}" Style="{ThemeResource ListViewItemContentTextBlockStyle}" Foreground="{ThemeResource PhoneMidBrush}" /> 
       <TextBlock Text="{Binding Subtitle}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" /> 
      </StackPanel> 
     </Grid> 
    </DataTemplate> 

    <DataTemplate x:Key="StandardDoubleLineItemTemplate"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="*"/> 
      </Grid.ColumnDefinitions> 

      <Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,9.5,0,0" Grid.Column="0" HorizontalAlignment="Left"> 
       <Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}" Height="79" Width="79"/> 
      </Border> 
      <StackPanel Grid.Column="1" Margin="14.5,0,0,0"> 
       <TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}" Foreground="Black"/> 
       <TextBlock Text="{Binding Subtitle}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" Foreground="DimGray"/> 
      </StackPanel> 
     </Grid> 
    </DataTemplate> 
</Page.Resources> 


<Page.BottomAppBar> 
    <CommandBar Background="Transparent"> 
     <AppBarButton Icon="Add" Label="Add" Click="add_onclick"/> 
     <AppBarButton Icon="Add" Label="Shake it!" /> 
    </CommandBar> 
</Page.BottomAppBar> 


<Grid x:Name="LayoutRoot"> 
    <Hub x:Name="Hub" x:Uid="Hub" Header="diary app hub" Margin="0,0,0,-59" Foreground="DimGray"> 
     <Hub.Background> 
      <ImageBrush ImageSource="ms-appx:/Assets/desk_paper.png" Stretch="None"/> 
     </Hub.Background> 
     <!--<HubSection x:Uid="HubSection1" Header="SECTION 1" DataContext="{Binding Groups}" HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}"> 
      <DataTemplate> 
       <ListView 
        ItemsSource="{Binding}" 
        IsItemClickEnabled="True" 
        ItemClick="GroupSection_ItemClick" 
        ContinuumNavigationTransitionInfo.ExitElementContainer="True"> 
        <ListView.ItemTemplate> 
         <DataTemplate> 
          <StackPanel Margin="0,0,0,27.5"> 
           <TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}" /> 
          </StackPanel> 
         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 
      </DataTemplate> 
     </HubSection>--> 



     <HubSection x:Uid="HubSection5" Header="Recent" 
        DataContext="{Binding Groups[0]}" HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}"> 
      <DataTemplate> 
       <ListView 
        AutomationProperties.AutomationId="ItemListViewSection5" 
        AutomationProperties.Name="Items In Group" 
        SelectionMode="None" 
        IsItemClickEnabled="True" 
        ItemsSource="{Binding Items}" 
        ItemTemplate="{StaticResource StandardDoubleLineItemTemplate}" 
        ItemClick="ItemView_ItemClick" 
        ContinuumNavigationTransitionInfo.ExitElementContainer="True"> 
       </ListView> 
      </DataTemplate> 
     </HubSection> 

     <HubSection x:Uid="HubSection2" Header="All notes" Width ="Auto" 
        DataContext="{Binding Groups[0]}" HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}" Height="659" > 
      <DataTemplate> 
       <GridView 
        Margin="0,9.5,0,0" 
        ItemsSource="{Binding Items}" 
        AutomationProperties.AutomationId="ItemGridView" 
        AutomationProperties.Name="Items In Group" 
        ItemTemplate="{StaticResource Standard200x180TileItemTemplate}" 
        SelectionMode="None" 
        IsItemClickEnabled="True" 
        ItemClick="ItemView_ItemClick" 
        ContinuumNavigationTransitionInfo.ExitElementContainer="True"> 
        <GridView.ItemsPanel> 
         <ItemsPanelTemplate> 
          <ItemsWrapGrid /> 
         </ItemsPanelTemplate> 
        </GridView.ItemsPanel> 
       </GridView> 
      </DataTemplate> 
     </HubSection> 

    </Hub> 
</Grid> 

回答

0

您需要提高PropertyChanged事件模型的属性。由于像Title,Subtitle这样的属性在修改PropertyChanged事件时不会引发UI通知。它应该是这样的:

private string _title; 
public string Title 
{ 
     get 
     { 
      return _title; 
     } 
     set 
     { 
      if(_title!=value) 
      { 
       _title=value; 
       OnPropertyChanged("Title"); 
      } 
     } 
} 

对其他属性做类似的操作。另外,您不需要为ObservableCollection提高PropertyChanged事件,因为ObservableCollection默认实现了INotifyPropertyChanged

+0

所以我只需要检测改变的属性?我的意思是,每个对象/项目都不能被修改,但是一旦用户点击保存按钮,每个对象/项目将被添加到'ObservableCollection'。我希望新添加的对象/项目在集线器页面上添加后显示。 – 2014-11-23 12:02:38

+0

'ObservableCollection'将在添加项目时负责更新UI,但每个对象的属性必须在更改时通知UI。如果您使用的是List而不是ObservableCollection,那么您也需要为集合提高事件。 – Sridhar 2014-11-23 13:23:26