简体   繁体   中英

Windows Phone 8.1 Hub Section Update Items (INotifyPropertyChanged)

I am trying to build a diary app that uses hub as user interface and update the UI after saving the diary. I already implemented the INotifyPropertyChanged but it didn't work. I want the item that is added after saving to appear on the hub immediately.

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;

}

here's my XAML File


<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>

You need to raise the PropertyChanged event for the model's properties. The UI doesn't get notified as properties like Title , Subtitle don't raise the PropertyChanged event when they are modified. It should be like this:

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

Do this similarly for other properties. Also, you don't need to raise the PropertyChanged event for an ObservableCollection as an ObservableCollection implements INotifyPropertyChanged by default.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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