WP8自动更新无法处理绑定

时间:2013-12-30 16:28:40

标签: c# binding windows-phone-8 inotifypropertychanged

我有一个WP8 Pivot应用程序,我将数据绑定到XAML:

<phone:LongListSelector Grid.Row="1" Name="llsLocations" ItemsSource="{Binding}" SelectionChanged="LongListSelector_OnSelectionChanged">
    <phone:LongListSelector.ItemTemplate>
        <DataTemplate>
            <Grid Margin="0,0,0,17">
                <Image Source="{Binding Icon}" HorizontalAlignment="Left" Height="54" Width="69" />
                <TextBlock Text="{Binding Location}" HorizontalAlignment="Left" Margin="80,0,0,0" />
                ....
                ....

在后面的代码中我分配了DataContext,如下所示:

public MainPage()
{
    InitializeComponent();
    DataContext = App.ViewModel.Signs;
}

ViewModel.Signs对象如下所示:

public ObservableCollection<SignsViewModel> Signs { get; set; }
public MainViewModel()
{
    Signs = new ObservableCollection<SignsViewModel>();
}

SignsViewModel对象中,我有一个NotifyPropertyChanged理论上应该只在属性发生变化时更新UI:

private int _id;
public int ID
{
    get { return _id; }
    set
    {
        if (value != _id)
        {
            _id = value;
            NotifyPropertyChanged("ID");
        }
    }
}

我有一个填充Signs对象的Web服务:

private void GetSigns_Completed(object sender, OpenReadCompletedEventArgs e)
{
    using (var sr = new StreamReader(e.Result))
    {
        var data = sr.ReadToEnd();
        var results = JsonConvert.DeserializeObject<GetSignsResponse>(data);
        App.ViewModel.Signs = results.Signs; // <--- This updates the Model
        App.ViewModel.IsDataLoaded = true;
        App.ViewModel.IsWaitingForData = false;
        var storage = new DataStorage();
        storage.SaveSigns(results.Signs);
    }
}

问题在于,当我调用服务并更新App.ViewModel.Signs时,用户界面似乎不会自行更新。我做错了什么?

1 个答案:

答案 0 :(得分:1)

我看到的主要问题是这行,特别是您评论的地方,“这会更新模型”:

    var results = JsonConvert.DeserializeObject<GetSignsResponse>(data);
    App.ViewModel.Signs = results.Signs; // <--- This updates the Model
    App.ViewModel.IsDataLoaded = true;

最有可能发生的事情是,您已将ViewModel.Signs对前一个ObservableCollection的引用中断。

MainViewModel构造函数中,您已将Signs属性设置为new ObservableCollection<SignsViewModel>()。但是,在上面的一行中,您使用results.Signs替换了该引用。

我要做的是确定这是否是问题而不是

    App.ViewModel.Signs = results.Signs; // <--- This updates the Model

将其替换为

    foreach (var sign in results.Signs) {
            App.ViewModel.Signs.Add(sign);
    }

您应该考虑的其他事项:

您的SignsViewModel不需要实现INotifyPropertyChanged(我假设您有),除非您希望对ID属性进行更新更新,即您希望用户能够Edit ID值。如果您只是显示它们,那么就没有必要实现INotifyPropertyChanged

我不建议将整个页面的DataContext设置为除最外层ViewModel之外的任何内容。而不是

DataContext = App.ViewModel.Signs;

我会选择

DataContext = App.ViewModel;

然后有一个

<phone:LongListSelector Grid.Row="1" Name="llsLocations" ItemsSource="{Binding Signs}" SelectionChanged="LongListSelector_OnSelectionChanged">

如果您计划拥有更多功能,那就更好了。

相关问题