我对C#和WPF还比较陌生。尽管我已经阅读了大量的文档、教程和之前的问题,但似乎找不到我的场景。
我的情况
我有一个使用C#编写的WPF应用程序,其中包含一个ListBox的单个窗口。 ListBox定义了一个DataTemplate来显示其项目,每个ListItem都有一个TextBox。
我在同一台机器上安装了Microsoft SQL Express服务器,其中包含一个名为Test
的数据库,其中包含一个名为Client
的视图,该视图公开另一个表的id INT PRIMARY KEY IDENTITY
和name VARCHAR(50) NOT NULL
列,并且有一个名为Client_update(@id, @name)
的存储过程,通过对相同表执行简单的UPDATE语句设置其id
为@id
的客户端的name
列。
我的目标
我的目标是在窗口加载时填充ListBox,并通过将焦点切换到GUI的另一个组件,将数据更改(包含在文本框中)持久保存到数据库(通过存储过程)。
我做了什么
我向项目添加了一个新的LINQ to SQL Classes元素,使用Visual Studio创建了一个名为DataClassesDataContext
的DataContext类。
我在Visual Studio中使用O-R Designer将视图映射到Class Client
和存储过程映射到方法Client_update(id, name)
。然后,我使用O-R Designer的GUI将表Client
的主键设置为id
,并将其默认编辑方法设置为Client_update(id, name)
(注意匹配存储过程和方法的参数)。
我的XAML代码(文件MainWindow.xaml.cs
)如下:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="Window_Loaded">
<ListBox x:Name="myListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=name Mode=TwoWay}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
我已将TextBox的Text属性绑定到代码后端在运行时设置的源的
name
属性上,且为双向绑定模式。
对于TextBox的数据更新,默认的触发器应该是OnLostFocus,所以我没有指定它。我的代码后端(文件
MainWindow.cs
)如下:namespace Test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Initialize the data context
DataClassesDataContext dataContext = new DataClassesDataContext();
//Define the query to retrieve the list of clients from the SQL Server
IEnumerable<Client> clients = from c in dataContext.Client
select c;
/* Set the item source to be the result of the query defined earlier
* (This also gets the query executed)
*/
myListBox.ItemsSource = clients;
}
}
}
我得到了什么
一开始,这个应用程序无法运行。在System.Data.Linq.dll
中抛出一个未处理的异常类型System.InvalidOperationException
,并携带着消息“成员'id'的AutoSync规范不正确。”。
通过在线搜索,我发现默认情况下 O-R Designer 在主键列上设置 Always
的 AutoSync 规范。将其设置为 OnUpdate
会引发相同的问题,而将其设置为 OnInsert
或 Never
则可以解决该问题。
然而,将其设置为这两个值只能使我的应用程序部分地工作,数据被显示,但更改不会保存到数据库中。(编辑应用程序数据后,我手动使用 Microsoft SQL Management Studio 进行了检查)
我的问题是什么
AutoSync 参数是什么,为什么会导致异常抛出?在此情况下,这是否是定义双向绑定的正确方式,还是我完全走错了方向?如果是后者,你可以给我任何指向正确策略的提示吗?
P.S. 如果代码没有正确高亮显示,我很抱歉。我已经阅读并尝试使用语法来应用Prettify,但由于某种原因没有XAML选项,即使使用XML和C#(cs)作为语言标记也无效,我不知道为什么。
EDIT #1: 高亮显示正常工作,只是预览中没有显示。
EDIT #2: 修正了一些拼写错误,视图、存储过程和类的名称是单数形式的。(即Client
而不是Clients
)