2010-11-18 1 views
0

В последнее время меня беспокоит другая проблема, и я вполне уверен, что это мои недостающие навыки WPF/MVVM, которые мешают мне выявить очевидное. Я уверен, что решение является простым, однако я не уверен, как его реализовать.Отображение данных в разных моделях без изменения данных модели

Я развиваюсь в WPF/C#, и я использую шаблон разработки MVVM.

Для простоты я задаю вопрос до самых основных компонентов.

Сценарий:

У меня есть модель, содержащая только целое число.

У меня есть родительская ViewModel, отображающая это целое число.

У меня есть две модели просмотра для детей, которые не входят в родительскую модель, и отображают это целое число. На одной из viewmodel у меня есть Command, увеличивая значение целого числа с 1. Значение изменяется в модели, которая реализует INotifyPropertyChanged, поэтому делает вторую ViewModel информацией об этом изменении, поэтому она может обновляться соответствующим образом.

Пока все работает нормально.

Тем не менее, меня интересует новая функция, и я не могу заставить ее работать. Скажем, что я на своей второй модели просмотра хочу отобразить целое число, но я хочу преобразовать способ отображения данных. Это должно быть сделано, однако, без изменения данных в модели. Если данные в модели меняются, преобразуемые данные будут соответственно изменяться.

В качестве примера предположим, что целое число равно 5. На второй модели просмотра я хочу отобразить целое число + 2, что означает 7. Затем данные изменяются на 6 из первой модели, что означает, что свойство на второй моделе изменения автоматически изменяется на 8.

Как это реализовано?

Несколько codepieces, чтобы показать, что система выглядит так далеко:

модели:

public DataModel() 
{ 
    data = new Data(); 

    data.Value = 2; 
} 

public Data data { get; set; } 

и класс данных:

public class Data : INotifyPropertyChanged 
{ 
    private int m_Value; 
    public int Value 
    { 
     get { return m_Value; } 
     set 
     { 
      if (m_Value != value) 
      { 
       m_Value = value; 
       OnPropertyChanged("Value"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 

     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(this, e); 
     } 
    } 

mainviewmodel

public class MainViewModel : ViewModelBase 
{ 
    readonly DataModel _dataModel; 

    public MainViewModel() 
    { 
     _dataModel = new DataModel(); 

     ViewModel1 = new 1ViewModel(this); 
     ViewModel2 = new 2ViewModel(this); 
    } 


    public 1ViewModel ViewModel1 { get; set; } 

    public 2ViewModel ViewModel2 { get; set; } 

    public Data Data 
    { 
     get { return _dataModel.data; } 

    } 



} 

А вот то, как ChildViewmodels связывает себя с объектом Data

public class 1ViewModel : ViewModelBase 
{ 

    private MainViewModel _mainViewModel; 

    public 1ViewModel(MainViewModel mainViewModel) 
    { 
     _mainViewModel = mainViewModel; 

    } 

    public Data Number 
    { 
     get { return _mainViewModel.data; } 

    } 

}

А на view1, я привязал свойство Number, как этого

<TextBlock Text="{Binding Path=Number.Value}" /> 

Опять же, я хочу чтобы создать второе свойство в viewmodel, которое отображает преобразованные данные на основе, но без изменения исходных данных и которые обновляются вместе с обновляемыми данными. Предпочтительно, это должен быть своего рода конвертер-метод, который преобразует данные в новые данные.

Надеюсь, вы в состоянии помочь.

ответ

1

ViewModel должен хранить данные, готовые для отображения, но не знающие о том, как он будет отображаться. Если вы хотите изменить способ отображения данных в вашем представлении, для этого вы должны использовать Converter. Это позволит вам использовать один и тот же ViewModel для нескольких просмотров и иметь разные представления.

Кроме того, упаковка ViewModel внутри ViewModel не обязательно так, как вы хотите. ViewModel обычно имеет связанный вид. Если у вас нет представления для ViewModel, обрабатывайте данные как типичные классы и продолжайте работу с одним ViewModel.

+0

Спасибо, я рассмотрю это сразу. И причина для меня, использующая больше режимов просмотра, заключается в том, что в главной модели просмотра есть tabcontrol, а eview sub-viewmodel - это другая вкладка. Все они имеют один и тот же источник данных, но они отображают данные по-разному. – Sagi1981

0

Используйте IValueConverter:

public class AddConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return (int)value + (int)parameter; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return (int)value - (int)parameter;    
    } 
} 

И в вашем XAML, добавить ресурс:

и обновить связывание:

Я использовал ConverterParameter здесь, но вы можете hardcode значение, если это необходимо. Возможно, вы захотите также добавить некоторые проверки в свой конвертер, так как это вызовет исключение, если типы неверны.