MVVM ViewModel INotifyPropertyChanged不更新属性 [英] MVVM ViewModel INotifyPropertyChanged not updating property
问题描述
我有一个我以前没见过的问题。在我的视图服务中,我有一种方法可以解雇"忙碌"的服务。表示应用程序处于忙碌状态的事件(因此用户将知道该应用程序正在"思考"并且未挂断)。
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屋!