我做了一个小项目来了解一下MVVM。这是一个计算器,可以计算何时可以下班回家。PropertyChangedEventHandler都是null时间,但绑定只能工作一次,为什么?
我做了一个UserControl
与两个文本框和一个简单的标签“TimePicker”。这个Usercontrol有一个ViewModel(主窗口甚至有一个),它管理一个Timepicker的时间。它有三个属性:一个称为TimeValue
的int,它只是小时和分钟的值,并且两个整数称为Hours
和Minutes
。我的两个文本框绑定到它们并显示它们。通过文本框设置一个值也重置时间,设置时间(通过属性)重置小时和分钟,两个文本框在设置此值后更新。
这个作品退出罚款。现在我想添加名为ReadOnly
的第二个属性。 TimePicker需要ReadOnly来显示时间。这是没有意义的手动设置这个时间,所以我想有可能设置两个文本框IsReadOnly
属性。
ReadOnly
现在是UserControl的第二个属性。因为我很懒,所以我想通过UserControl直接绑定属性和两个文本框,并且只将IsReadOnly
-Property绑定到UserControl。
这是我的想法的代码(用户控件):
public partial class TimeBox : UserControl, INotifyPropertyChanged
{
private SingleTimeViewModel viewModel;
//... other Properties
public static DependencyProperty ReadOnlyProperty = DependencyProperty.Register("ReadOnly", typeof(Boolean), typeof(TimeBox), new PropertyMetadata(false));
// Schnittstellen-Ereignis
public event PropertyChangedEventHandler PropertyChanged;
protected internal void OnPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
public TimeBox()
{
InitializeComponent();
viewModel = new SingleTimeViewModel(SingleTime.CreateSingleTime());
this.DataContext = viewModel;
}
//... Code of other Properties
private bool _ReadOnly;
public bool ReadOnly
{
get
{
return _ReadOnly;
}
set
{
if (_ReadOnly == value)
return;
_ReadOnly = value;
OnPropertyChanged("ReadOnly");
}
}
//... Other Methods
}
这是通过XAML绑定到两个文本框(绑定Text
导致视图模型,IsReadOnly应绑定到时间盒):
<UserControl x:Name="TimeBoxControl" x:Class="TimeCalculator.TimeBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
... >
<WrapPanel Grid.Column="7" HorizontalAlignment="Stretch" Margin="0,0,0,0" Grid.Row="1" VerticalAlignment="Center" >
<TextBox x:Name="txtBxHours" ... Text="{Binding Hours}" ... IsReadOnly="{Binding ReadOnly, ElementName=TimeBoxControl}" />
<Label x:Name="lblSeparator" ... />
<TextBox x:Name="txtBxMinutes" ... Text="{Binding Minutes}" ... IsReadOnly="{Binding ReadOnly, ElementName=TimeBoxControl}" />
</WrapPanel>
</UserControl>
我在InitializeComponent
之后在我的项目的主窗口的构造函数中只读取了这些值。所以我用下面几行:
this.TmBxMayGo.ReadOnly = true;
this.TmBxMustGo.ReadOnly = true;
this.TmBxTimeUntilMayGo.ReadOnly = true;
this.TmBxTimeUntilMustGo.ReadOnly = true;
this.TmBxCurrentOvertime.ReadOnly = true;
这不起作用,一些调试后我发现它并没有因为PropertyChangedEventHandler PropertyChanged
总是null
。 我搜索了很多以找到解决这个问题的方法,但是我没有做出任何常见的错误(例如忘记: INotifyPropertyChanged
,在字符串中的错误名称或其他)。
我终于放弃了,并通过ViewModel。但后来我意识到,PropertyChangedEventHandler PropertyChanged
也是null
当我通过ViewModel设置,但文本框是ReadOnly后调用。
现在这两个问题,我有:
- 是否有意义作出自己的视图模型为单用户控件?
- 这是为什么呢?
PropertyChanged
是null
两次,但只能工作一次?
我想知道为什么你需要INotifyPropertyChanged派生自UserControl的类。您可以充分利用依赖属性来获得更好的控制和灵活性。 – pushpraj
在分配_ReadOnly之前,请选中“if(_Enabled == value)”。是通过设计还是你必须检查“if(_ReadOnly == value)”? :) –
删除所有。你不应该在'DependencyObject'中实现'INotifyPropertyChanged'。这个想法是通过将所有的属性放在一个单独的,名为“ViewModel”的POCO类中来实际“分离”UI和行为。 –