Windows Phone 8.1 Hub 部分更新项 (INotifyPropertyChanged)

本文关键字:更新 INotifyPropertyChanged Phone Hub Windows | 更新日期: 2023-09-27 18:31:46

我正在尝试构建一个使用集线器作为用户界面的日记应用程序,并在保存日记后更新 UI。我已经实现了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>

Windows Phone 8.1 Hub 部分更新项 (INotifyPropertyChanged)

您需要

引发模型属性的PropertyChanged事件。UI 不会收到像 Title 这样的属性的通知,Subtitle在修改它们时不会引发 PropertyChanged 事件。它应该是这样的:

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

对其他属性执行类似的操作。此外,无需引发ObservableCollectionPropertyChanged 事件,因为默认情况下ObservableCollection实现INotifyPropertyChanged