0

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

带有 ViewModel 作为 DataContext 的 UserControl,例如:

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 有几个文本框,但正确绑定的最佳方法是什么?

谢谢你的帮助,问候。

4

3 回答 3

3

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

阅读您的评论后,我将详细说明我的文本框示例。

第一个重要的事情是 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方法可以触发相应的事件。这告诉视图该属性已更改,它必须自行更新。

请注意Mode=TwoWayXAML 中的 。这意味着,无论值在哪一侧发生变化,另一侧都会立即反映变化。所以如果用户在一个TwoWaybound中改变了一个值TextBox,那么对应的 ViewModel 属性就会自动改变!反之亦然:如果您以编程方式更改 ViewModel 属性,则 View 将刷新。

如果要为多个数据项显示多个文本框,则必须在 ViewModel 中引入更多属性并相应地绑定它们。也许 a里面ListBox有灵活数量的TextBoxes 是一个解决方案,就像@Haspemulator 已经回答一样。

将数据绑定到集合控件

TestUserControl我猜你有一个控件(比如 a ListView)来显示加载的东西的列表。因此,将该控件与 ViewModel 中的列表绑定

<ListView ... ItemsSource="{Binding GetAllData}" ... />

首先你必须明白Binding的意思不是“读取数据然后忘记 ViewModel”。相反,只要 View 存在,您就可以将 View 绑定到 ViewModel(及其属性)。从这个角度来看,这AllData是一个比GetAllData(感谢@Malcolm O'Hare)更好的名字。

现在在您的代码中,每次视图读取AllData属性时,DataRepository都会创建一个新属性。由于 Binding,这不是您想要的,而是您希望DataRepository在 View 的整个生命周期内拥有一个实例,用于读取初始数据,以后可以用于更新 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 将自动更新。

于 2013-01-22T21:05:40.133 回答
2

您的物业名称不好。您应该将其称为 AllData,而不是 GetAllData。

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

在那种情况下,你会做

<ListBox ItemsSource="{Binding GetAllData}" />
于 2013-01-22T21:05:11.090 回答
0

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

<ListBox.ItemTemplate>
    <DataTemplate>
        <TextBox Text={Binding SomeOtherData,Mode=TwoWay} />
    </DataTemplate>
</ListBox.ItemTemplate>

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

于 2013-01-22T21:13:37.917 回答