MVVM-Light и WP7 ViewModel не работает надгробие - PullRequest
1 голос
/ 02 февраля 2011

Я попытался выполнить действия, описанные в статье Джуста Ван Шаика о могиле , но не смог заставить ее работать на меня.Я, без сомнения, делаю что-то не так.В моей ViewModel:

private string _foobar ="init";

public string testStr
{
    get
    {
        return _foobar;
    }

    set
    {
        _foobar = value;
    }
}

И на моей странице:

<TextBox x:Name="tBoxTest" Text="{Binding testStr, Mode=TwoWay}" />

Во время работы приложения изменение значения в tBoxTest просто отлично устанавливает _foobar, но попробуйте его сериализоватькак будто он забыл экземпляр ???Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

1 голос
/ 02 февраля 2011

Я смог заставить работать надгробную плиту, а также сделать объект видимым для всех моих моделей ViewModel, выполнив следующее:

В классе Model я добавил:

private static Model1 _instance;
public static Model1 Instance
{
    get { return _instance; }
    set { _instance = value; }
}

public static void CreateNew()
{
    if (_instance == null)
    {
        _instance = new Model1();

        _instance.FirstString = "init";
    }
}

Затем в ApplicationExtensions.cs я добавил:

  public static void SaveToIsolatedStorage(this Application app, Model1 model)
    {
        var dataFileName = GetIsFile((model.GetType()));
        using (var userAppStore =
                 IsolatedStorageFile.GetUserStoreForApplication())
        {
            if (userAppStore.FileExists(dataFileName))
            {
                userAppStore.DeleteFile(dataFileName);
            }
            using (var iss = userAppStore.CreateFile(dataFileName))
            {
                SilverlightSerializer.Serialize(model, iss);
            }
        }
    }

И в App.xaml.cs я изменил LoadModel () на:

private void LoadModel()
{
    try
    {
        Model1.Instance = this.RetrieveFromIsolatedStorage<Model1>();
    }
    catch (Exception) { }

    if (Model1.Instance == null) Model1.CreateNew();
}

В моих файлах ViewModel все это работает так:

public string TestStr
{
    get
    {
        return Model1.Instance.FirstString;
    }

    set
    {
        Model1.Instance.FirstString = value;
    }
}

И под этим я подразумеваю, что объект Model1 становится сериализованным, а захоронение работает - по крайней мере, я получаю то, что, как мне кажется, я хочу. Я много раз проверял его, перемещаясь между приложениями, настройками телефона, выключая и включая телефон, блокируя его и вызывая его, находясь в приложении с другого телефона. Производительность при десериализации отличная. И я могу работать с Vars.

При этом г-н Ван Шайк ответил на запрос о помощи следующим образом: «Если вы выполняете подклассы из MVVMLight ViewModelBase, это делает, а затем вам следует вызвать RaisePropertyChanged из вашего установщика следующим образом:

приватная строка _foobar = "init";

публичная строка TestStr { получить { вернуть _foobar; }

    set
    {
         RaisePropertyChanged("TestStr");
        _foobar = value;
    }
}

RaisePropertyChanged уведомляет любые представления прослушиваний (т. Е. Привязанный к нему TextBox) о том, что свойство изменяется и что оно должно обновлять их содержимое. Это важнейший механизм. "

Так что я буду работать с тем, что я первоначально пытался, но с добавлением RaisePropertyChanged, чтобы увидеть, что это делает.

UPDATE

Несмотря на то, что я реализовал RaisedPropertyChanged (используя фрагмент кода mvvminpc) в моем файле MainViewModel.cs, это по-прежнему не оказывало (как бы хорошо ни было для других) сериализацию чего-либо, созданного в ViewModel. Я, вероятно, все еще делаю что-то не так, но это также может быть связано с тем, что модели представлений наследуются от защищенного класса ( ответ от Laurent Bugnion ). Я (очень неохотно) пытался изменить этот класс с защищенного на общедоступный и перекомпилировать, но в моем случае это не помогло, и я ненавижу раскладывать библиотеку, на которую ссылаются, как это. Во всяком случае, я просто пока продвигаюсь вперед, создав экземпляр Model1 в App.xaml.cs. Кажется, работает. Пока я занимался этим, я изменил один из методов Ван Шаика, чтобы принимать любой тип объекта:

public static void SaveToIsolatedStorage<T>(this Application app, T obj)
where T : class
{
    var dataFileName = GetIsFile(typeof(T));
    using (var userAppStore =
                IsolatedStorageFile.GetUserStoreForApplication())
    {
        if (userAppStore.FileExists(dataFileName))
        {
            userAppStore.DeleteFile(dataFileName);
        }
        using (var iss = userAppStore.CreateFile(dataFileName))
        {
            SilverlightSerializer.Serialize(obj, iss);
        }
    }
}
0 голосов
/ 02 февраля 2011

Из кода, который вы разместили, нет мгновенного ответа.

Мой совет по отладке:

  • если вы скопировали код именно из этой статьи, добавьте что-нибудь (окно сообщения?) В пустой обработчик catch - `catch (Exception) {}

  • использовать отладчик для установки точек останова в методах LoadModel и SaveToIsolatedStorage

  • использовать эти точки останова для перехода по коду загрузки и сохранения - правильно ли код загружается и сохраняется?

Если честно, с такими проблемами, провести небольшое расследование самостоятельно гораздо лучше, чем задавать вопросы здесь (ИМО!)

...