使用MVVM/LINQ和XAML填充文本框
本文关键字:填充 文本 XAML MVVM LINQ 使用 | 更新日期: 2023-09-27 18:05:34
我想了解MVVM和LINQ,所以我设置了一个测试数据库。基于XAML的视图有一个单一的文本框-绑定到"组织名称"。然而,我一直在一个例子上工作,但我有"var结果"的麻烦(我认为)。
出于某种原因,我在标题"XamlParseException发生"下得到一个运行时错误,我认为这是查询字符串,而不是在字段中拉。
按照要求,完整的错误是:{"'调用类型'WpfApplication2上的构造函数。与指定绑定约束匹配的主窗口抛出了异常。行号"4",行位"9"。"}
public partial class MainWindow : Window
{
private egwEntities db = new egwEntities();
MyViewModel mvm = new MyViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = mvm;
var result = (from o in db.egw_addressbook select o).FirstOrDefault();
if (result != null)
{
mvm.OrgName = result.org_name;
}
}
}
public class MyViewModel
{
public string OrgName { get; set; }
}
}
下面是我在视图中使用的XAMLI:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="EGW" Height="350" Width="525">
<Grid>
<TextBox Text="{Binding OrgName}" HorizontalAlignment="Left" Height="41" Margin="72,94,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="318"/>
</Grid>
</Window>
错误信息表明
var result = (from o in db.egw_addressbook select o).FirstOrDefault();
if (result != null) {
mvm.OrgName = result.org_name;
}
失败,导致主窗口构造失败,给出XamlParse异常。您可以通过删除这些行来测试它,看看它是否运行。
MVVM
MVVM形状的目标之一是减少视图(窗口)和数据之间的链接。在上面的例子中,您从Model-View- viewmodel形状中丢失了模型(或者更确切地说,您已经合并了模型和视图)。
你可以这样试试。
将数据访问分离到存储库中—使测试更容易
public interface IRepository {
IEnumerable<Organization> GetOrganizations();
}
我已经使用了一个虚拟存储库,您可以将其替换为您的DataContext代码
public IEnumerable<Organization> GetOrganizations() {
return new[] {new Organization() {Name = "A name"}};
}
为应用程序添加一个模型
public class AppModel {
public AppModel(IRepository repository) {
var result = (from o in repository.GetOrganizations() select o).FirstOrDefault();
if (result != null) {
OrgName = result.Name;
}
}
public string OrgName { get; private set; }
}
说明:
这可以通过几种方式实现。我们倾向于有非常薄的ViewModel,在ViewModel和model之间有很多成员复制(例如,组织名称出现在两者中);ViewModels主要是传递和格式化。这不是唯一的方法(甚至可能不是最好的)。我将在MVVM形状上进行网络搜索以跟踪
我稍微调整了一下视图模型代码。如果不写入组织名,则应设置为只读
public class MainWindowViewModel {
private readonly AppModel _model;
public MainWindowViewModel(AppModel model) {
_model = model;
}
public string OrgName {
get { return _model.OrgName; }
}
}
如果组织名称是只读的,那么绑定需要是单向的。添加数据上下文定义有助于查找绑定错误。
<Window x:Class="Sus.ProofsOfConcept.SimpleMvvm.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:MyExamples.SimpleMvvm"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance views:MainWindowViewModel, IsDesignTimeCreatable=false }"
Title="EGW" Height="350" Width="525">
<Grid>
<TextBox Text="{Binding OrgName, Mode=OneWay}" HorizontalAlignment="Left" Height="41" Margin="72,94,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="318"/>
</Grid>
</Window>
默认的运行机制(在App.Xaml中命名的启动窗口)不再工作,如果没有依赖注入(DI),你可以使用
public partial class App : Application {
protected override void OnStartup(StartupEventArgs e) {
var model = new AppModel(new Repository());
var viewModel = new MainWindowViewModel(model);
var view = new MainWindow() {DataContext = viewModel};
view.Show();
}
}
该错误与您的XAML有关,如果您有语法错误,它将抛出运行时错误。如果您的var result
行有问题,您可能会收到一些其他错误。
试着把你的textrap行改成这样:
TextWrapping=TextWrapping.Wrap