我已经开始了一个MVVM项目,现在我正在使用正确的DataBinding。我的项目有:
A UserControl whit a ViewModel as DataContext like:
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,但是正确绑定的最好方法是什么?
谢谢你的帮助,致敬。
发布于 2013-01-23 05:05:40
编辑:将数据绑定到多个文本框
在阅读完您的评论后,我将详细介绍我的textboxes示例。
第一件重要的事情是,ViewModel将对视图中的事物进行建模,这样视图就可以在它需要的结构中获得所需的所有信息。这意味着,如果视图中有多个textboses,那么在ViewModel中需要多个string Properties,每个textbox对应一个字符串属性。
在您的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中引入更多属性并相应地绑定它们。也许一个内部有灵活数量的TextBoxes的ListBox是一个解决方案,就像@Haspemulator已经回答过的那样。
根据集合控件绑定数据的
在TestUserControl中,我猜您有一个控件(类似于ListView)来显示已加载内容的列表。因此,使用以下命令将控件绑定到ViewModel中列表
<ListView ... ItemsSource="{Binding GetAllData}" ... />首先,您必须了解绑定并不意味着“读取数据,然后忘记ViewModel”。相反,只要视图存在,就将视图绑定到ViewModel (及其属性)。从这个角度来看,AllData是一个比GetAllData更好的名字(感谢@Malcolm O‘’Hare)。
现在,在您的代码中,每次视图读取AllData属性时,都会创建一个新的DataRepository。由于绑定,这并不是您想要的,相反,您希望在视图的整个生命周期中拥有一个DataRepository实例,该实例用于读取初始数据,如果底层数据库发生更改(可能带有事件),稍后可以使用该实例来更新视图。
要启用这种行为,您应该将AllData属性的类型更改为ObservableCollection,以便视图可以在发生更改时自动更新列表。
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将自动更新。
发布于 2013-01-23 05:05:11
您的属性名称不正确。你应该叫它AllData,而不是GetAllData。
由于您要返回一个集合,因此您可能应该使用某种列表控件(ListBox、ListView)。
如果是那样的话,你就会做
<ListBox ItemsSource="{Binding GetAllData}" />发布于 2013-01-23 05:13:38
古腾·阿本德:)正如它已经提到的,由于您要返回集合,所以最好使用ListBox。关于将ObservableCollection作为缓存的评论也是绝对有效的。我要补充的是,如果你需要让你的数据是可编辑的,你应该在ItemTemplate中使用TextBox:
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text={Binding SomeOtherData,Mode=TwoWay} />
</DataTemplate>
</ListBox.ItemTemplate>在这种情况下,如果用户编辑框中的文本,数据将在您的数据对象中更新,以便稍后可以将其保存在数据库中。
https://stackoverflow.com/questions/14467666
复制相似问题