Как обновить отображение элемента вида на основе изменения значения свойства методом ВМ? - PullRequest
0 голосов
/ 14 мая 2018

Нужна помощь. Здравствуйте все. Я действительно понятия не имею, как обновить элементы представления, когда значение свойства обновляется с помощью моего Egzecute метода внутри MsgViewModel, вызываемого с помощью public ICommand Start. Например, я хочу сделать одну кнопку STOP видимой, а другую START свернутой, когда свойство Status меняет свое значение с Stopped на Sending. Также обратите внимание, что видимость обновляется корректно, когда свойство Status изменяется конструктором ViewModels (по умолчанию при запуске для меня) Status = Models.SendingStatus.Stopped; или Status = Models.SendingStatus.Sending;.

Вид:

<!--START, to be collapsed-->
<Button Grid.Row="0"
                Grid.Column="4"
                Background="#80B584"
                Visibility="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Mode=OneWay,
            Converter={StaticResource boolStart}}" Margin="0,145,443.667,-0.333"
                Command="{Binding Path=Start}">
            <TextBlock Text="START" TextWrapping="Wrap" TextAlignment="Center"/>
        </Button>
        <!--STOP, to be viewed-->
        <Button Grid.Row="0"
                Background="#FF8A8A"
                Visibility="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Mode=OneWay,
            Converter={StaticResource boolStop}}" Margin="0,145,443.667,-0.333">
            <TextBlock Text="STOP" TextWrapping="Wrap" TextAlignment="Center"/>
        </Button>

ViewModel:

private Models.MsgModel message= new Models.MsgModel (); //model instance
public MsgViewModel() //constructor, by default makes staus "Stopped"
        {
            Status = Models.SendingStatus.Stopped;
        }
public Models.SendingStatus Status
        {
            get
            {
                return message.Status;
            }
            set
            {
                message.Status = value;
            }
        }
private ICommand start;
        public ICommand Start //command called by START button, supposed to collapse it, and show STOP button
        {
            get
            {
                if (start == null)
                    start = new RelayCommand(
                    o =>
                    {
                        Egzecute();
                    });
                return start;
            }
        }
public void Egzecute() //method called by the command
        {
            Status = Models.SendingStatus.Sending;
            var openDialog = new Powiadomienie();
            openDialog.ShowPowiadomienie(Status.ToString(), "Powiadomienie"); //shows updated SendingStatus, but the View is not updating to it
        }

Модель:

public enum SendingStatus: byte { Sending, Waiting, Stopped} //enum for Status property
public class MsgModel : INotifyPropertyChanged
private SendingStatus status;
        public SendingStatus Status //Status model property
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
                OnPropertyChanged("Status");
            }
        }
public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(params string[] propertyNames) 



        {
            if (PropertyChanged != null)
            {
                foreach (string propertyName in propertyNames) 
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

Конвертеры:

public class BooleanStart : IValueConverter //text decoration
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ViewModels.MsgViewModel mvm = new ViewModels.MsgViewModel();
            bool bvalue = (bool)value;
            if (mvm.Status == Models.SendingStatus.Sending|| mvm.Status == Models.SendingStatus.Waiting)
            {
                return Visibility.Collapsed;
            }
            else
            {
                return Visibility.Visible;
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter,
        CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class BooleanStop : IValueConverter //text decoration
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ViewModels.MsgViewModel mvm = new ViewModels.MsgViewModel();
            bool bvalue = (bool)value;
            if (mvm.Status == Models.SendingStatus.Sending|| mvm.Status == Models.SendingStatus.Waiting)
            {
                return Visibility.Visible;
            }
            else
            {
                return Visibility.Collapsed;
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter,
        CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

У меня вопрос, как обновить View после вызова метода по команде?

1 Ответ

0 голосов
/ 15 мая 2018

Хорошо, через несколько часов я понял свою ошибку. Конструкция конвертера была неправильной. Связывание должно быть другим, и ViewModel обновляется с уведомлением об изменении свойства. Преобразователи:

public class BooleanStart : IValueConverter //text decoration
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Models.SendingStatus sendingStatus = (Models.SendingStatus)value;
            if (sendingStatus == Models.SendingStatus.Sending || sendingStatus == Models.SendingStatus.Waiting)
            {
                return Visibility.Collapsed;
            }
            else
            {
                return Visibility.Visible;
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter,
        CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class BooleanStop : IValueConverter //text decoration
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Models.SendingStatus sendingStatus = (Models.SendingStatus)value;
            if (sendingStatus == Models.SendingStatus.Sending || sendingStatus == Models.SendingStatus.Waiting)
            {
                return Visibility.Visible;
            }
            else
            {
                return Visibility.Collapsed;
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter,
        CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

Для переплета:

<!--START-->
        <Button Grid.Row="0"
                Grid.Column="4"
                Background="#80B584"
                Visibility="{Binding Path=Status, Converter={StaticResource boolStart}}" Margin="0,145,443.667,-0.333"
                Command="{Binding Path=Start}">
            <TextBlock Text="START" TextWrapping="Wrap" TextAlignment="Center"/>
        </Button>
        <!--STOP-->
        <Button Grid.Row="0"
                Background="#FF8A8A"
                Visibility="{Binding Path=Status, Converter={StaticResource boolStop}}" Margin="0,145,443.667,-0.333"
                Command="{Binding Path=Start}">
            <TextBlock Text="STOP" TextWrapping="Wrap" TextAlignment="Center"/>
        </Button>

Метод ViewModel`:

public void Egzecue()
        {
            Status = Models.SendingStatus.Sending;
            OnPropertyChanged("Status");
            var openDialog = new Powiadomienie();
            openDialog.ShowPowiadomienie(Status.ToString(), "Powiadomienie");
        }
...