MVVM ViewModel INotifyPropertyChanged不更新属性 [英] MVVM ViewModel INotifyPropertyChanged not updating property

查看:88
本文介绍了MVVM ViewModel INotifyPropertyChanged不更新属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个我以前没见过的问题。在我的视图服务中,我有一种方法可以解雇"忙碌"的服务。表示应用程序处于忙碌状态的事件(因此用户将知道该应用程序正在"思考"并且未挂断)。

I have an issue I haven't seen before. In my view service, I have a method that is meant to fire a "Busy" event to indicate that the application is in a busy status (so the user will know that the app is "thinking" and not hung up).

private bool isBusy; public event EventHandler<EventArgs<bool>> BusyChanged; public void ShowBusy(bool isBusy) { if (this.isBusy == isBusy) {return;} this.isBusy = isBusy; BusyChanged?.Invoke(this, new EventArgs<bool>(this.isBusy)); }

此方法为isBusy(true)触发一个BusyChanged事件,为isBusy触发一个事件(false)。此事件与mainViewModel的属性相关联,而mainViewModel又在UI中绑定了一个项目。

This methods fires a BusyChanged event one for isBusy(true) and one for isBusy(false). This event is tied to a property of the mainViewModel which in turn has an item in the UI that is bound to it.

viewService.BusyChanged += (_, e) => mainWindowViewModel.IsBusy = e.Data;

现在我正在使用一个简单的配色方案,指示忙或默认不忙。

For now I'm using a simple color scheme that indicates either busy or defaulted not busy.

"IsBusy" MainViewModel中的属性有一个NotifyOfPropertyChange方法(当然它实现了INotifyPropertyChanged接口)。

The "IsBusy" property in the MainViewModel has a NotifyOfPropertyChange method (which of course implements the INotifyPropertyChanged interface).

    public bool IsBusy
    {
        get => this.isBusy;
        set
        {
            this.isBusy = value;
            NotifyOfPropertyChange(() => this.IsBusy);
        }
    }

并且XAML项(如上所述)具有绑定到该属性的DataTrigger样式触发器。

And the XAML item (as mentioned) has a DataTrigger style trigger binding to that property.

<Ellipse x:Name="ActionStatusEllipse" Width="17" Height="17" HorizontalAlignment="Right" 
                             Margin="0,0,10,0" VerticalAlignment="Center" >

                        <Ellipse.Style>
                            <Style TargetType="{x:Type Ellipse}" >
                                <Setter Property="Stroke" Value="#03A631"/>
                                <Setter Property="StrokeThickness" Value="4" />

                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsBusy}" Value="False">
                                        <Setter Property="Stroke" Value="#03A631" />
                                    </DataTrigger>

                                    <DataTrigger Binding="{Binding IsBusy}" Value="True">
                                        <Setter Property="Stroke" Value="#E9F80C" />
                                    </DataTrigger>
                                </Style.Triggers>

                            </Style>
                        </Ellipse.Style>
                    </Ellipse>


运行应用程序时,颜色不会按预期更改。然而,奇怪的是如果我在IsBusy属性中的NotifyOfPropertyChange行之后添加一个MessageBox,那么它可以工作。我已经尝试了很多东西,但似乎无法破解
这个问题。为什么在属性中添加MessageBox会导致UI元素看到属性更改但是没有MessageBox就看不到它?有没有人见过这种行为?我希望这个问题描述足够清楚。

When I run the application, the color does not change as expected. However, what is strange is that if I add a MessageBox after the NotifyOfPropertyChange line in the IsBusy property then it works. I've tried a number of things but can't seem to crack this issue. Why would adding a MessageBox in the property cause the UI element to see the property change but not see it without the MessageBox? Has anyone else seen this behavior? I hope this problem description is clear enough.

推荐答案

您好TonyRhys,

Hi TonyRhys,

根据您的描述和您的代码,我发现您要实现INotifyPropertyChanged接口以通知IsBusy属性已更改,但UI不按预期更改?

According to your description and your code, I find you want to implement INotifyPropertyChanged interface to notify IsBusy property changed, but the UI don't changed as expected?

如果是,我发现你使用了viewService.BusyChanged事件来改变IsBusy属性,我做了一个你可以看看的样本,我可以根据需要更新UI到IsBusy属性,我在Button.cllick事件中更改了IsBusy属性。

If yes, I find you use viewService.BusyChanged event to change IsBusy property, I do one sample you can take a look, I can update UI according to IsBusy property, I change IsBusy property in Button.cllick event.

<Ellipse
            x:Name="ActionStatusEllipse"
            Width="17"
            Height="17">
            <Ellipse.Style>
                <Style TargetType="{x:Type Ellipse}">
                    <Setter Property="Stroke" Value="#03A631" />
                    <Setter Property="StrokeThickness" Value="4" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsBusy}" Value="False">
                            <Setter Property="Stroke" Value="#03A631" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding IsBusy}" Value="True">
                            <Setter Property="Stroke" Value="#E9F80C" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Ellipse.Style>
        </Ellipse>

        <Button
            Name="btn1"
            Width="200"
            Height="30"
            Click="btn1_Click" Margin="20"
            Content="btn1" />


 public partial class Window11 : Window
    {
        public status statusp { get; set; }
        public Window11()
        {
            InitializeComponent();
            statusp = new status() { IsBusy = false };
            this.DataContext = statusp;
        }
          
        private void btn1_Click(object sender, RoutedEventArgs e)
        {
            statusp.IsBusy = true;
        }
    }

    public class status:ViewModelBase
    {
        private bool _IsBusy;
        public bool IsBusy
        {
            get { return _IsBusy; }
            set
            {
                _IsBusy = value;
                RaisePropertyChanged("IsBusy");
            }
        }
    }


 public class ViewModelBase:INotifyPropertyChanged
    {
        
        public event PropertyChangedEventHandler PropertyChanged;

          
        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }





最好的问候,

Cherry

Cherry


这篇关于MVVM ViewModel INotifyPropertyChanged不更新属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆