我正在开发一个WPF项目,我的视图模型有超过90个属性。我有一个"保存"点击的按钮我将属性保存到DB。我需要禁用“保存”按钮,直到至少修改了其中一个属性。我不能去为每个属性设置OnPropertyChanged事件处理(仅仅因为它对于90多个属性来说太麻烦)。有没有我可以这样做,即使一个属性被更改我应该得到通知,以便我可以启用保存按钮?
<StackPanel>
<StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="{x:Static res:Resources.SaveToDB}" Command="{Binding Save}" IsEnabled="{Binding CanSaveToDB}" Margin="0,0,4,0" HorizontalAlignment="Center" Style="{StaticResource OverlayDialogButtonCentered}" FontSize="14"/>
<Button Content="{x:Static res:Resources.DiscardDBSave}" Command="{Binding DiscardSave}" Margin="0,0,4,0" HorizontalAlignment="Center" Style="{StaticResource OverlayDialogButtonCentered}" FontSize="14"/>
</StackPanel>
<StackPanel>
<views:MySampleAppView1 DataContextChanged="MySampleApp_DataContextChanged" DataContext="{Binding MySampleApp.View1}"/>
</StackPanel>
<StackPanel>
<views:MySampleAppView2 DataContextChanged="MySampleApp_DataContextChanged" DataContext="{Binding MySampleApp.View2}"/>
</StackPanel>
<StackPanel>
<views:MySampleAppView3 DataContextChanged="MySampleApp_DataContextChanged" DataContext="{Binding MySampleApp.View3}"/>
</StackPanel>
<StackPanel>
<views:MySampleAppView4 DataContextChanged="MySampleApp_DataContextChanged" DataContext="{Binding MySampleApp.View4}"/>
</StackPanel>
<StackPanel>
<views:MySampleAppView5 DataContextChanged="MySampleApp_DataContextChanged" DataContext="{Binding MySampleApp.View5}"/>
</StackPanel>
<StackPanel>
<views:MySampleAppView6 DataContextChanged="MySampleApp_DataContextChanged" DataContext="{Binding MySampleApp.View6}"/>
</StackPanel>
<StackPanel>
<views:MySampleAppView7 DataContextChanged="MySampleApp_DataContextChanged" DataContext="{Binding MySampleApp.View7}"/>
</StackPanel>
</StackPanel>
然后上面的每个View都有WPF控件。我有上面每个View的视图模型。然后有一个主视图模型代表上面提到的代码。
答案 0 :(得分:1)
一个典型的解决方案是只实现一次(通常在基类上),并从每个属性的setter调用它,传递已更改的属性的名称。这仍然相对麻烦。另一种方法是使用Fody之类的工具自动添加此逻辑。
如果所有属性都调用单个OnPropertyChanged
实现,则可以在那里实现设置脏标志的逻辑(以及启用“保存”按钮)。
答案 1 :(得分:0)
PropertyChanged事件可以指示对象上的所有属性 已使用null或String.Empty作为属性名称进行更改 在PropertyChangedEventArgs。
答案 2 :(得分:0)
有两种方式可以想到。
首先,您并不需要在每个属性设置器中触发唯一的属性更改通知,因为您的按钮&#39; IsEnabled属性不会绑定到视图模型中的那些90个奇怪属性中的任何一个。我真正想要的是让某种IsDirty属性在其他属性发生变化时被设置,将其绑定到按钮的IsEnabled属性,并在更改IsDirty时执行OnPropertyChanged通知程序。
但是,如果您仍然不想在90个属性设置器中执行任何特殊操作,则另一个选项是在视图控件中自行处理更改事件。例如,在所有TextBox中,订阅TextChanged。在事件处理程序中,在视图模型上设置IsDirty属性。 (您可以在控件和样式中订阅这些处理程序,这样您就不必将事件处理程序设置为90次。)
除了这两个想法,我认为没有办法做你想做的事。 C#中没有内置机制来在类属性发生变化时得到通知。如果不是在属性中,您将不得不自己拦截更改。 setters,然后在他们被绑定的控件上使用事件处理程序。