[英]MVVM DataBinding
我已經開始了MVVM項目,現在我堅持使用正確的DataBinding。 我的項目有:
一個UserControl帶有一個ViewModel作為DataContext,例如:
public partial class TestUserControl: UserControl
{
public TestUserControl()
{
this.DataContext = new TestUserControlViewModel();
}
}
ViewModel代碼為(BaseViewModel類包含PropertyChangedEventHandler):
public class TestUserControlViewModel : BaseViewModel
{
public KrankenkasseControlViewModel()
{}
public IEnumerable<DataItem> GetAllData
{
get
{
IGetTheData src= new DataRepository();
return src.GetData();
}
}
}
IGetTheData是DataContext的接口:
public interface IGetTheData
{
IEnumerable<DataItem> GetData();
}
}
最后是DataRepository代碼:
public class DataRepository : IGetTheData
{
private TestProjectDataContext dax = new TestProjectDataContext();
public IEnumerable<DataItem> GetData()
{
return (from d in this.dax.TestData
select new DataItem
{
ID = d.ID,
SomeOtherData = d.SomeOtherData
});
}
}
我的UserControl有幾個TextBoxes,但是正確綁定的最佳方法是什么?
謝謝您的幫助,問候。
編輯:對多個文本框綁定數據
閱讀您的評論后,我將詳細說明我的文本框示例。
首先重要的是ViewModel將對View中的事物進行建模,以便View在所需的結構中獲取所需的所有信息。 這意味着,如果視圖中有多個文本框,則視圖模型中將需要多個字符串屬性,每個文本框一個。
在您的XAML中,您可能會遇到類似
<TextBox Text="{Binding ID, Mode=TwoWay}" />
<TextBox Text="{Binding SomeOtherData, Mode=TwoWay}" />
並在您的ViewModel中
public class TestUserControlViewModel : BaseViewModel {
private string id;
private string someOtherData;
public TestUserControlViewModel() {
DataItem firstItem = new DataRepository().GetData().First();
this.ID = firstItem.ID;
this.SomeOtherData = firstItem.SomeOtherData;
}
public string ID {
get {
return this.id;
}
set {
if (this.id == value) return;
this.id = value;
this.OnPropertyChangedEvent("ID");
}
}
public string SomeOtherData {
get {
return this.someOtherData;
}
set {
if (this.someOtherData == value) return;
this.someOtherData = value;
this.OnPropertyChangedEvent("SomeOtherData");
}
}
}
在這里,我假設您的BaseViewModel
有一個OnPropertyChangedEvent
方法來觸發相應的事件。 這告訴View屬性已更改,並且必須對其進行自我更新。
請注意XAML中的Mode=TwoWay
。 這意味着,值更改的哪一側都無所謂,另一側將立即反映更改。 因此,如果用戶在TwoWay
綁定的TextBox
更改值,則相應的ViewModel屬性將自動更改! 反之亦然:如果以編程方式更改ViewModel屬性,則視圖將刷新。
如果要為多個數據項顯示多個文本框,則必須在ViewModel中引入更多屬性,並進行相應的綁定。 那么也許里面有靈活數量的TextBox
的ListBox
是一個解決方案,就像@Haspemulator已經回答了。
將數據綁定到集合控件
在TestUserControl
我想您有一個控件(如ListView
)來顯示已加載內容的列表。 因此,將控件與ViewModel中的列表綁定在一起
<ListView ... ItemsSource="{Binding GetAllData}" ... />
首先,您必須了解Binding的意思不是“讀取數據,然后忘記ViewModel”。 相反,只要View持續存在,就將View綁定到ViewModel(及其屬性)。 從這個角度來看, AllData
比GetAllData
(感謝@Malcolm O'Hare)。
現在在您的代碼中,每次View讀取AllData
屬性時,都會創建一個新的DataRepository
。 由於綁定的原因,這不是您想要的,而是希望在View的整個生命周期中都擁有一個DataRepository
實例,該實例用於讀取初始數據,並且可以在以后用於更新View(如果基礎)數據庫更改(可能帶有事件)。
要啟用這種行為,您應該將AllData
屬性的類型更改為ObservableCollection
,以便在發生更改時View可以自動更新列表。
public class TestUserControlViewModel : BaseViewModel
private ObservableCollection<DataItem> allData;
public TestUserControlViewModel() {
IGetTheData src = new DataRepository();
this.allData = new ObservableCollection<DataItem>(src.GetData());
}
public ObservableCollection<DataItem> AllData {
get {
return this.allData;
}
}
public void AddDataItem(DataItem item) {
this.allData.Add(item);
}
}
現在,如果以后再調用AddDataItem
,ListView將自動更新。
您的財產名稱不正確。 您應該將其命名為AllData,而不是GetAllData。
由於要返回集合,因此可能應該使用某種列表控件(ListBox,ListView)。
那樣的話你會做
<ListBox ItemsSource="{Binding GetAllData}" />
Guten Abend。 :)如前所述,由於您要返回集合,因此最好使用ListBox。 關於將ObservableCollection作為緩存的評論也絕對有效。 我要補充一點,如果需要編輯數據,則應在ItemTemplate內使用TextBox:
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text={Binding SomeOtherData,Mode=TwoWay} />
</DataTemplate>
</ListBox.ItemTemplate>
在這種情況下,如果用戶在框中編輯文本,則數據將在您的數據對象中更新,以便以后可以將其保存在數據庫中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.