首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVVM DataBinding

MVVM DataBinding
EN

Stack Overflow用户
提问于 2013-01-23 04:44:56
回答 3查看 3.4K关注 0票数 0

我已经开始了一个MVVM项目,现在我正在使用正确的DataBinding。我的项目有:

A UserControl whit a ViewModel as DataContext like:

代码语言:javascript
复制
public partial class TestUserControl: UserControl
{
   public TestUserControl()
   {
       this.DataContext = new TestUserControlViewModel();
   }
}

ViewModel代码是(BaseViewModel类包含PropertyChangedEventHandler):

代码语言:javascript
复制
public class TestUserControlViewModel : BaseViewModel
{
   public KrankenkasseControlViewModel()
   {}

   public IEnumerable<DataItem> GetAllData
   {
      get
      {
          IGetTheData src= new DataRepository();
          return src.GetData();
      }
   }
}

IGetTheData是DataContext的接口:

代码语言:javascript
复制
public interface IGetTheData
{
   IEnumerable<DataItem> GetData();
}

}

最后是DataRepository代码:

代码语言:javascript
复制
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,但是正确绑定的最好方法是什么?

谢谢你的帮助,致敬。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-23 05:05:40

编辑:将数据绑定到多个文本框

在阅读完您的评论后,我将详细介绍我的textboxes示例。

第一件重要的事情是,ViewModel将对视图中的事物进行建模,这样视图就可以在它需要的结构中获得所需的所有信息。这意味着,如果视图中有多个textboses,那么在ViewModel中需要多个string Properties,每个textbox对应一个字符串属性。

在您的XAML中,您可以使用如下内容

代码语言:javascript
复制
<TextBox Text="{Binding ID, Mode=TwoWay}" />
<TextBox Text="{Binding SomeOtherData, Mode=TwoWay}" />

在你的ViewModel中

代码语言:javascript
复制
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中列表

代码语言:javascript
复制
<ListView ... ItemsSource="{Binding GetAllData}" ... />

首先,您必须了解绑定并不意味着“读取数据,然后忘记ViewModel”。相反,只要视图存在,就将视图绑定到ViewModel (及其属性)。从这个角度来看,AllData是一个比GetAllData更好的名字(感谢@Malcolm O‘’Hare)。

现在,在您的代码中,每次视图读取AllData属性时,都会创建一个新的DataRepository。由于绑定,这并不是您想要的,相反,您希望在视图的整个生命周期中拥有一个DataRepository实例,该实例用于读取初始数据,如果底层数据库发生更改(可能带有事件),稍后可以使用该实例来更新视图。

要启用这种行为,您应该将AllData属性的类型更改为ObservableCollection,以便视图可以在发生更改时自动更新列表。

代码语言:javascript
复制
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将自动更新。

票数 3
EN

Stack Overflow用户

发布于 2013-01-23 05:05:11

您的属性名称不正确。你应该叫它AllData,而不是GetAllData。

由于您要返回一个集合,因此您可能应该使用某种列表控件(ListBox、ListView)。

如果是那样的话,你就会做

代码语言:javascript
复制
<ListBox ItemsSource="{Binding GetAllData}" />
票数 2
EN

Stack Overflow用户

发布于 2013-01-23 05:13:38

古腾·阿本德:)正如它已经提到的,由于您要返回集合,所以最好使用ListBox。关于将ObservableCollection作为缓存的评论也是绝对有效的。我要补充的是,如果你需要让你的数据是可编辑的,你应该在ItemTemplate中使用TextBox:

代码语言:javascript
复制
<ListBox.ItemTemplate>
    <DataTemplate>
        <TextBox Text={Binding SomeOtherData,Mode=TwoWay} />
    </DataTemplate>
</ListBox.ItemTemplate>

在这种情况下,如果用户编辑框中的文本,数据将在您的数据对象中更新,以便稍后可以将其保存在数据库中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14467666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档