Как отправить модель проверки сообщений для просмотра в шаблоне MVVM? - PullRequest
4 голосов
/ 03 апреля 2009

У меня есть небольшое тестовое приложение WPF MVVM, в котором представление позволяет пользователю изменять имя или фамилию клиента, а полное имя автоматически изменяется, поэтому связь переходит от M-to-MV-to- V и обратно, все полностью отделено, пока все хорошо.

Но теперь, глядя на то, как я начну расширять это для создания больших приложений с шаблоном MVVM, я обнаружил, что разделение является препятствием, а именно:

  • как я буду делать сообщения проверки , например если вернуться в модель в установщике LastName, я добавлю код, который запрещает задавать имена более 50 символов, как я могу отправить сообщение в представление , сообщающее ему, что оно отображает слишком длинное имя?

  • в сложных приложениях У меня могут быть десятки представлений на экране за один раз, но я понимаю, что в MVVM каждому представлению назначен один-единственный ViewModel для предоставления ему данных и поведение, так как получается, что представления могут взаимодействовать друг с другом , например В приведенном выше примере проверки, что, если в модели клиента мы хотим проинформировать конкретный «MessageAreaView» для отображения сообщения «Фамилия может содержать только 50 символов». Как нам передать это в стеке этому конкретному представлению?

CustomerHeaderView.xaml (Просмотреть):

<UserControl x:Class="TestMvvm444.Views.CustomerHeaderView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <StackPanel HorizontalAlignment="Left">
            <ItemsControl ItemsSource="{Binding Path=Customers}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <StackPanel Orientation="Horizontal">
                                <TextBox
                                Text="{Binding Path=FirstName, Mode=TwoWay}" 
                                Width="100" 
                                Margin="3 5 3 5"/>
                                <TextBox 
                                Text="{Binding Path=LastName, Mode=TwoWay}" 
                                Width="100"
                                Margin="0 5 3 5"/>
                                <TextBlock 
                                Text="{Binding Path=FullName, Mode=OneWay}" 
                                Margin="0 5 3 5"/>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </StackPanel>
    </Grid>
</UserControl>

Customer.cs (модель):

using System.ComponentModel;

namespace TestMvvm444.Model
{
    class Customer : INotifyPropertyChanged
    {

        public int ID { get; set; }
        public int NumberOfContracts { get; set; }

        private string firstName;
        private string lastName;

        public string FirstName
        {
            get { return firstName; }
            set
            {
                if (firstName != value)
                {
                    firstName = value;
                    RaisePropertyChanged("FirstName");
                    RaisePropertyChanged("FullName");

                }
            }
        }

        public string LastName
        {
            get { return lastName; }
            set
            {
                if (lastName != value)
                {
                    lastName = value;
                    RaisePropertyChanged("LastName");
                    RaisePropertyChanged("FullName");
                }
            }
        }

        public string FullName
        {
            get { return firstName + " " + lastName; }
        }



        #region PropertChanged Block
        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
        #endregion
    }
}

Ответы [ 3 ]

6 голосов
/ 03 апреля 2009

Для проверки предложите вашей модели представления реализовать IDataErrorInfo. Что касается связи между представлениями, не бойтесь писать сервисы пользовательского интерфейса (например, сервис сообщений, который позволяет и просматривать модель для предоставления сообщений, которые будут отображаться где-то в пользовательском интерфейсе). Или, если существует жесткая связь между моделями представления (например, одна модель представления владеет другой), то модель-владелец может содержать ссылку на модель дочернего представления.

2 голосов
/ 06 апреля 2009

Действительно простой способ добавить сообщения проверки - использовать привязку.

Добавьте в вашу модель представления уведомляемое свойство, определяющее, должно ли отображаться сообщение проверки:

private Boolean _itemValidatorDisplayed;
public Boolean ItemValidatorDisplayed
{
    get { return _itemValidatorDisplayed; }
    set
    {
        _itemValidatorDisplayed= value;
        _OnPropertyChanged("ItemValidatorDisplayed");
    }
}

Добавьте класс конвертера, который преобразует bool в видимость:

using System;
using System.Windows;

namespace xxx
{
    public class BoolToVisibilityConverter : IValueConverter
    {
        public bool Negate { get; set; }

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool val = System.Convert.ToBoolean(value);
            if (!Negate)
            {
                return val ? Visibility.Visible : Visibility.Collapsed;
            }
            else
            {
                return val ? Visibility.Collapsed : Visibility.Visible;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Привязка к свойству из вида и применение конвертера:

    <UserControl x:Class="ViewClass"
    ...
    >
        <UserControl.Resources>
            <contract:BoolToVisibilityConverter Negate="False"
                                                x:Key="BoolToVisibilityConverter" />
        </UserControl.Resources>

...

<TextBlock Visibility="{Binding Converter={StaticResource BoolToVisibilityConverter}, Path=ItemValidatorDisplayed}" />

...

</UserControl>

Вам необходимо установить ViewModel в качестве текстового контекста представления:

namespace xxx
{
    public partial class ViewClass: UserControl
    {
        public ViewClass()
        {
            InitializeComponent();

            this.DataContext = new ViewClass_ViewModel();
        }
}
}

Бинго - отлично работающая проверка, отправляемая в любое представление, которое хочет подписаться на эту ViewModel / Property.

0 голосов
/ 07 июля 2009

Вы также сможете привязать валидацию к коллекции исходных объектов в SL3: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...