RaiseProperty изменил не обновляющий интерфейс - PullRequest
2 голосов
/ 30 августа 2011

У меня проблемы с тем, чтобы мой пользовательский интерфейс обновлял два списка, чтобы он обновлялся должным образом при изменении модели ViewModel.

Во-первых, основная логика за страницей:

Фильм - это объект с названием и разновидностью MovieDetails. Некоторые MovieDetail отличаются от других, поскольку они подробны , что является прославленным способом сказать, что они более важны. Я использую два ListBoxes, чтобы разделить эти MovieDetails на сложенные ListBoxes, один для «Подробного» и один для «NotDetailed» Если фильм не имеет атрибутов «Подробно», соответствующий список скрывается с помощью BooleanToVisibilityConverter (и наоборот)

Когда я перехожу на страницу, я устанавливаю Movie, которому соответствует эта страница, и она должна RaisePropertyChanged предупредить AllMoviesDetail ObservableCollection, что она должна снова получить Movies.MovieDetailFetchedList. Оттуда AllMoviesDetail предупредит двух ObservableCollections (Detailed, NotDetailed), что они должны быть повторно get.

На самом деле RaisePropertyChanged на NotDetailedMovieDetails или DetailedMovieDetails, похоже, тоже ничего не делает. (И соответствующий HasNotDetailedMovieDetails, Has...)

Что работает, однако, если я добавляю больше элементов в список, событие CollectionChanged, похоже, запускает и повторно активирует список. Я также смог сделать это, создав сначала ObservableCollections в коде var temp = DetailedMoviesDetail;

public class MoviesDetailViewModel : ViewModelBase
{
    #region Property Names

    public const string MoviePropertyString = "Movie";
    public const string AllMoviesDetailPropertyString = "AllMoviesDetail";
    public const string DetailedMoviesDetailPropertyString = "DetailedMoviesDetail";
    public const string NotDetailedMoviesDetailPropertyString = "NotDetailedMoviesDetail";
    public const string HasNotDetailedMoviesDetailPropertyString = "HasNotDetailedMoviesDetail";
    public const string HasDetailedMoviesDetailPropertyString = "HasDetailedMoviesDetail";
    public const string NotDetailedHeaderPropertyString = "NotDetailedHeader";

    #endregion


    public MoviesDetailViewModel()
    {
        if (IsInDesignMode)
        {
            Movie = DesignDataStore.MovieList[0];
            Movie.Category = Category.DDA;
        }
    }

    private Movie _Movie;

    /// <summary>
    /// The Movie for which to browse MoviesDetail. It is expected when setting this property, that MoviesDetail for it have been downloaded previously.
    /// </summary>
    /// <remarks>The 'Master' property for this ViewModel. All properties are Dependent on this and the underlying property MoviesDetailList</remarks>
    /// <seealso cref="MovieDetailFetchedList"/>
    public Movie Movie
    {
        get { return _Movie; }
        set
        {
            if (_Movie != value)
            {
                if (_Movie != null)
                    _Movie.MovieDetailFetchedList.CollectionChanged -= MoviesDetailListChanged;


                _Movie = value;

                RaisePropertyChanged(MoviePropertyString);
                RaisePropertyChanged(StatementPeriodAvailablePropertyString);
                RaisePropertyChanged(NotDetailedMoviesDetailPropertyString);
                Movie.MovieDetailFetchedList.CollectionChanged += MoviesDetailListChanged;

                RaisePropertyChanged(AllMoviesDetailPropertyString);

                RaisePropertyChanged(DetailedMoviesDetailPropertyString);

                RaisePropertyChanged(NotDetailedHeaderPropertyString);
            }
        }
    }

    private void MoviesDetailListChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (var item in e.NewItems)
            {
                if (((MovieDetail) item).IsDetailed())
                    DetailedMoviesDetail.Add(item as MovieDetail);
                else
                    NotDetailedMoviesDetail.Add(item as MovieDetail);
            }
        }
        else
        {
            RaisePropertyChanged(AllMoviesDetailPropertyString);
            RaisePropertyChanged(DetailedMoviesDetailPropertyString);
            RaisePropertyChanged(NotDetailedMoviesDetailPropertyString);
        }
    }




    #endregion

    private MovieDetailFetchedList _allMoviesDetail;
    public MovieDetailFetchedList AllMoviesDetail
    {
        get
        {
            if (Movie == null)
                return new MovieDetailFetchedList();

            return _allMoviesDetail ?? (AllMoviesDetail = Movie.MovieDetailFetchedList);
        }
        set
        {
            if (_allMoviesDetail != value)
            {
                if (_allMoviesDetail != null)
                    _allMoviesDetail.CollectionChanged -= MoviesDetailListChanged;
                _allMoviesDetail = value;
                _allMoviesDetail.CollectionChanged += MoviesDetailListChanged;

                RaisePropertyChanged(AllMoviesDetailPropertyString);
                //force update
                DetailedMoviesDetail = NotDetailedMoviesDetail = null;
                RaisePropertyChanged(DetailedMoviesDetailPropertyString);
                RaisePropertyChanged(HasDetailedMoviesDetailPropertyString);
                RaisePropertyChanged(NotDetailedMoviesDetailPropertyString);
                RaisePropertyChanged(HasNotDetailedMoviesDetailPropertyString);
            }

        }
    }

    public bool HasNotDetailedMoviesDetail { get { return NotDetailedMoviesDetail != null && NotDetailedMoviesDetail.Count > 0; } }



    private ObservableCollection<MovieDetail> _notDetailedMoviesDetail;
    public ObservableCollection<MovieDetail> NotDetailedMoviesDetail
    {
        get
        {
            if (Movie == null) return new ObservableCollection<MovieDetail>();

            return AllMoviesDetail;
               return _notDetailedMoviesDetail ?? //make sure RaisePropertyChanged happens by using property setter
              (NotDetailedMoviesDetail = AllMoviesDetail.Where(mem => !mem.IsDetailed()).ToObservableCollection());
        }
        set
        {
            _notDetailedMoviesDetail = value;
            RaisePropertyChanged(NotDetailedMoviesDetailPropertyString);
            RaisePropertyChanged(HasNotDetailedMoviesDetailPropertyString);
        }
    }

    public bool HasDetailedMoviesDetail
    { get { return DetailedMoviesDetail != null && DetailedMoviesDetail.Count > 0; } }

    private ObservableCollection<MovieDetail> _DetailedMoviesDetail;
    public ObservableCollection<MovieDetail> DetailedMoviesDetail
    {
        get
        {
            if (Movie == null) return new ObservableCollection<MovieDetail>();

            return AllMoviesDetail;
            return _DetailedMoviesDetail ?? //make sure RaisePropertyChanged happens by using property setter
            (DetailedMoviesDetail = AllMoviesDetail.Where(mem => mem.IsDetailed()).ToObservableCollection());
        }
        set
        {
            _DetailedMoviesDetail = value;
            RaisePropertyChanged(DetailedMoviesDetailPropertyString);
            RaisePropertyChanged(HasDetailedMoviesDetailPropertyString);
        }
    }


    private string _DetailedHeader;
    public string DetailedHeader
    {
        get { return _DetailedHeader ?? (_DetailedHeader = AppResources.in_available); }
        set { _DetailedHeader = value; }
    }

    public string NotDetailedHeader
    {
        get { return (Movie != null && Movie.Category == Category.DRAMA) ? AppResources.Movie_MoviesDetail : AppResources.not_in_available; }
    }
}

1 Ответ

4 голосов
/ 30 августа 2011

Все получатели вашей собственности (кроме AllMoviesDetail) имеют два заявления о возврате. Поскольку будет выполнено только первое, значения не присваиваются, а события PropertyChanged не пересекаются.

...