我做了一個小項目來了解一下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和行爲。 –