我正在尝试构建一个使用hub作为用户界面的日记应用程序,并在保存日记后更新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>
答案 0 :(得分:0)
您需要为模型的属性引发PropertyChanged
事件。由于Title
,Subtitle
等属性在修改后不会引发PropertyChanged事件,因此不会收到通知。它应该是这样的:
private string _title;
public string Title
{
get
{
return _title;
}
set
{
if(_title!=value)
{
_title=value;
OnPropertyChanged("Title");
}
}
}
对其他属性执行此操作。另外,默认情况下,PropertyChanged
实施ObservableCollection
ObservableCollection
INotifyPropertyChanged
事件不需要提升{{1}}。