wpf+access 一个小项目的总结
最近使用WPF+Access 做了一个很小的项目,由于之前都是很MS SQL,对Access并不是很了解,虽说数据库都差多,但是这次我感觉还是差很多,也能是Access是轻量级的数据库吧,很多写法都不支持!WPF与之前写的WinForm也有很大的差别,下面我把自己再这个项目中遇到的一些问题及解决方法简单的记录一下,如果有不妥之处,还望大神斧正!
1、Access中与MS sql的不同之处
1、exists用法,if(exists(select 1 from a)) 这种用法在ms sql中判断是否有数据,使用也很方便,但在access中不支持这种写法,如果有需要另行别法!
2、我用ADO.NET读取access库中的数据,不支持多个结果集,无法一次性返回多个表中的数据,只能一个一个获取!
3、access表中的字段(假设Birthday DateTime 可空),不能手动插入null,你可以不插入这个字段,但不能为该字段插入null;之前在ms sql中插入这类字段的时间,一个insert a(birthday) values({0}) 语句就行,无非判断一下birthday是否有值,如果没有值赋值为null即可,但在Access中像这种情况可能需要拼接了!
4、关联删除语句中,在access中必须添加distinctrow关键字,如:
delete distinctrow f.* from
(select FID from Re_Customer_Family where CID=1) r
inner join(select ID from Family) f on r.FID= f.ID
5、还有一中就是access中,没有row_number()函数,如果想实现分页的话,需要使用top n 来实现!下面是查询第11条到第20条记录的语句:
select a.* from
(select top 20 * from student ) a
left join ( select top 10 * from student ) b on a.ID=b.ID
where iif(b.ID,'0','1')='1'
access中没if,但有iif(表达式,值1,值2);如果表达式为真,返回值1,否则 返回值2!
2、有关Wpf与winform的差别
1、WPF应用程序,遇到的第一个问题就是,我没有找到Program类和Main方法!这个让我很郁闷,难到WPF已经不用Main了,那入口点再哪啊?后来Google一翻,发现它隐藏在App.g.cs中,
后来自己又添加了一个Program类,里面写了Main方法实现一台机器只能运动一个实例,这时生成 提示出错:已经有一个入口点了!
class Program { [STAThread] public static void Main(string[] agrs) { bool createdNew; using (Mutex mutex = new Mutex(false, "025CFB63-2148-44D3-BA12-E4ADDA183B7F", out createdNew)) { if (createdNew) { App app = new App(); app.InitializeComponent(); app.Run(); } else { MessageBox.Show("已经启动了一个程序,请先退出!", "系统提示", MessageBoxButton.OK, MessageBoxImage.Error); } } } }
解决方法:右键项目--》应用程序--》启动对象--》选择刚才添加的Program类即可!
2、PasswordBox控件,之前在winForm中只需要调协TextBox控件的PassworkChar属性就行了,而在wpf中确是单独的密码控件!
3、动态绑定显示CheckBox控件问题,
前台界面xaml代码:
<WrapPanel> <ItemsControl x:Name="itemsControlSport"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal"></WrapPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Border Padding="5"> <WrapPanel> <CheckBox IsChecked="{Binding Checked}" Tag="{Binding ID}" Content="{Binding Name}"/> </WrapPanel> </Border> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </WrapPanel>
后台绑定代码相对简单:
//运动 DataTable dt = BLL.PBase.GetSportList(); if (dt == null) return; itemsControlSport.ItemsSource = dt.DefaultView;
这一切正确,数据显示也很正常
获取界面哪些被选中也没问题,得到这个CheckBox集合后随你怎么操作!
/// <summary> /// 获取DataTemplate控件的函数,返回的是一个集合 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <param name="name">表示查找所有指定类型的控件</param> /// <returns></returns> public List<T> GetChildObjects<T>(DependencyObject obj, string name) where T : FrameworkElement { DependencyObject child = null; List<T> childList = new List<T>(); for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++) { child = VisualTreeHelper.GetChild(obj, i); if (child is T && (((T)child).Name == name || string.IsNullOrEmpty(name))) { childList.Add((T)child); } childList.AddRange(GetChildObjects<T>(child, ""));//指定集合的元素添加到List队尾 } return childList; } //获取所有CheckBox List<CheckBox> collection = GetChildObjects<CheckBox>(itemsControlSport, "");
到目前为止这个动态绑定CheckBox显示,获取CheckBox集合都没问题!
但接下来出现了一个问题,小第我Google了两翻也没查到问题的原因,详细说明一下问题:
我做了一个窗体,该窗体用于添加用户信息和修改用户信息,
当添加用户时一切正常,也可以正常保存,但是当修改用户信息时,窗体首先加载基础数据也就是上面看到的(潜水、航海...),接下来就是读取该用户选择了 哪些选项,让Checkbox选中,
在我绑定基础数据后,直接用上面的方法去获取CheckBox集合循环判断哪个是该用户所拥有的就选中,但是CheckBox集合总是为空(绑定显示Checkbox和获取CheckBox都在窗体加载事件中),
我认为是这样,当我们动态绑定控件时,Window_Load事件没执行完成就去获取,是无法获取的,后来我修改为:如果是添加直接如上方式来绑定显示,如果是修改的话,那让基础数据添加一列是否选中列,再绑定。
下面一点就不是专指WPF了,我们把程序打包后在win7/vista中安装在系统盘中,如果有些IO的操作是没有权限的,需要我以管理权限运行才行!而且我们打包时创建的快捷方式右键也没有“以管理员身份运行”这个选项,
解决方法是,右键项目,添加一个应用程序描述文件,如:app.manifest 打开后
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <!-- UAC 清单选项 如果要更改 Windows 用户帐户控制级别,请用以下节点之一替换 requestedExecutionLevel 节点。 <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> 指定 requestedExecutionLevel 节点将会禁用文件和注册表虚拟化。 如果要利用文件和注册表虚拟化实现向后 兼容性,则删除 requestedExecutionLevel 节点。 --> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo>
把level="asInvoker"改成level="requireAdministrator"管理员权限就OK啦。
建议将该文件拖入Properties目录下,如下所示:
这个之后,我们再把这个项目打包后,安装运行时,它就会自动以管理员的身份运行了。
以上就是我在项目遇到和解决的一此问题!