如何根据VM方法的属性值更改来更新视图元素显示?

时间:2018-05-14 17:55:55

标签: c# wpf mvvm icommand

需要一些帮助。大家好。当我使用Egzecute内的MsgViewModel方法更新属性值时,我真的不知道如何更新视图元素,并使用public ICommand Start调用。例如,当属性STOP更改其值STARTStatus时,我想要显示一个按钮Stopped,另一个Sending折叠。还请注意,当使用ViewModels构造函数更改属性Status时(默认情况下为我开始)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>

视图模型:

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 :(得分:0)

好的,几个小时后我发现了我的错误。转换器的构造是错误的。绑定应该是不同的,并且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");
        }