主从结构在企业级应用中相当常见,这里结合我的例子谈一下wpf中主从结构列表展示的常用做法,具体效果见 wpf企业级开发中的几种常见业务场景

  首先,Model有两种,主表对应model(假设为modelA),从表对应的model(假设为modelB),两种model分别用于绑定列表,就是普通列表的绑定。

  其次,由于要实现联动效果(即选择主表中的一条记录显示从表的记录),故而我们的ViewModel里面必须设计一个SelectedModelA用来绑定选中项,SelectedModelA变化时去更新modelB列表的数据源(通常SelectedModelA中会包含一个集合,不过我这里由于其他原因单独弄了个集合,逻辑其实大同小异)。

  下面是我的代码,由于夹杂着一些业务,仅供参考,其实读者只需明白主表的选中项作为从表UI的数据源即可。

  UI部分,可先直接看下具体效果 wpf企业级开发中的几种常见业务场景,绑定部分主要看两个DataGrid即可。

  1. <Grid>
  2. <Grid.ColumnDefinitions>
  3. <ColumnDefinition Width="200"/>
  4. <ColumnDefinition/>
  5. </Grid.ColumnDefinitions>
  6. <HeaderedContentControl>
  7. <HeaderedContentControl.Header>
  8. <DockPanel>
  9. <TextBlock VerticalAlignment="Center" Text="{DynamicResource ProductClassify_Header_Classify}" DockPanel.Dock="Left"/>
  10. <StackPanel VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">
  11. <Button Name="Button_RefreshClassify" Style="{StaticResource RefreshIconButton}" Content="{DynamicResource Common_Refresh}" Command="{Binding TreeVM.RefreshCommand}"/>
  12. </StackPanel>
  13. </DockPanel>
  14. </HeaderedContentControl.Header>
  15. <local:ClassifyTreeControl DataContext="{Binding TreeVM}"/>
  16. </HeaderedContentControl>
  17.  
  18. <HeaderedContentControl Name="Header_Product" Grid.Column="1">
  19. <HeaderedContentControl.Header>
  20. <DockPanel>
  21. <TextBlock VerticalAlignment="Center" Text="{DynamicResource ProductList_Header_Product}" DockPanel.Dock="Left"/>
  22. <StackPanel VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">
  23. <Button Name="Button_RefreshClassify2" Style="{StaticResource RefreshIconButton}" Content="{DynamicResource Common_Refresh}" Command="{Binding RefreshCommand}"/>
  24. <Button Name="Button_AddProduct" Visibility="{Binding AddButtonVisibility}" IsEnabled="{Binding CanAdd}" Style="{StaticResource AddIconButton}" Content="{DynamicResource Common_Add}" Click="Button_AddProduct_Click"/>
  25. <Button Name="Button_ModifyProduct" Visibility="{Binding ModifyButtonVisibility}" IsEnabled="{Binding CanModify}" Style="{StaticResource ModifyIconButton}" Content="{DynamicResource Common_Modify}" Click="Button_ModifyProduct_Click"/>
  26. <Button Name="Button_DeleteProduct" Visibility="{Binding DeleteButtonVisibility}" Style="{StaticResource DeleteIconButton}" Content="{DynamicResource Common_Delete}" Command="{Binding DeleteCommand}"/>
  27. </StackPanel>
  28. </DockPanel>
  29. </HeaderedContentControl.Header>
  30. <DataGrid Name="DataGrid_Product" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct}" SelectionMode="Single" AutoGenerateColumns="False" IsReadOnly="True">
  31. <DataGrid.Columns>
  32. <DataGridTextColumn Header="{DynamicResource Product_Num}" Binding="{Binding Num}" Width="120"/>
  33. <DataGridTextColumn Header="{DynamicResource Product_Name_CH}" Binding="{Binding Name_CH}" Width="100"/>
  34. <DataGridTextColumn Header="{DynamicResource Product_Name_EN}" Binding="{Binding Name_EN}" Width="100"/>
  35. <DataGridTextColumn Header="{DynamicResource Product_Unit}" Binding="{Binding Unit}" Width="50"/>
  36. <DataGridTextColumn Header="{DynamicResource Product_Weight}" Binding="{Binding Weight}" Width="100"/>
  37. <DataGridTextColumn Header="{DynamicResource Product_Size}" Binding="{Binding Size}" Width="100"/>
  38. <DataGridTemplateColumn Header="{DynamicResource Product_CanSale}">
  39. <DataGridTemplateColumn.CellTemplate>
  40. <DataTemplate>
  41. <CheckBox IsThreeState="False" IsChecked="{Binding CanSale}" IsEnabled="False" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" HorizontalAlignment="Center" Width="50"/>
  42. </DataTemplate>
  43. </DataGridTemplateColumn.CellTemplate>
  44. </DataGridTemplateColumn>
  45. <DataGridTextColumn Header="{DynamicResource Product_ReferencePrice}" Binding="{Binding ReferencePrice}" Width="100"/>
  46. <DataGridTemplateColumn Header="{DynamicResource Product_StopProduction}">
  47. <DataGridTemplateColumn.CellTemplate>
  48. <DataTemplate>
  49. <CheckBox IsThreeState="False" IsChecked="{Binding StopProduction}" IsEnabled="False" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" HorizontalAlignment="Center" Width="50"/>
  50. </DataTemplate>
  51. </DataGridTemplateColumn.CellTemplate>
  52. </DataGridTemplateColumn>
  53. <DataGridTextColumn Header="{DynamicResource Product_MinSaleCount}" Binding="{Binding MinSaleCount}" Width="80"/>
  54. <DataGridTextColumn Header="{DynamicResource Product_PackageCount}" Binding="{Binding PackageCount}" Width="80"/>
  55. <DataGridTextColumn Header="{DynamicResource Product_Remark}" Binding="{Binding Remark}" Width="200"/>
  56. </DataGrid.Columns>
  57. <DataGrid.RowStyle>
  58. <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
  59. <Setter Property="ToolTip">
  60. <Setter.Value>
  61. <Border Width="100" Height="100" BorderBrush="#FF7DB6D8" BorderThickness="1" Padding="1">
  62. <Border.Resources>
  63. <product:PicUrlConverter x:Key="urlConverter"/>
  64. </Border.Resources>
  65. <Image Source="{Binding ProductPic, Converter={StaticResource urlConverter}}"/>
  66. </Border>
  67. </Setter.Value>
  68. </Setter>
  69. <EventSetter Event="MouseDoubleClick" Handler="Button_ModifyProduct_Click"/>
  70. </Style>
  71. </DataGrid.RowStyle>
  72. </DataGrid>
  73. </HeaderedContentControl>
  74. </Grid>

  ViewModel中相关代码

  1. public class ProductListVM : ViewModelBase
  2. {
  3. public ProductListVM()
  4. {
  5. LoadData();
  6. TreeVM.SelectedChanged += (s, e) =>
  7. {
  8. LoadData();
  9. if (TreeVM.SelectedModel != null && !string.IsNullOrEmpty(TreeVM.SelectedModel.ID))
  10. CanAdd = true;
  11. else
  12. CanAdd = false;
  13. };
  14. }
  15.  
  16. private ClassifyTreeVM _treeVM;
  17. public ClassifyTreeVM TreeVM
  18. {
  19. get
  20. {
  21. return _treeVM ?? (_treeVM = new ClassifyTreeVM());
  22. }
  23. }
  24.  
  25. private tb_product _selectedProduct;
  26. public tb_product SelectedProduct
  27. {
  28. get
  29. {
  30. return _selectedProduct;
  31. }
  32. set
  33. {
  34. _selectedProduct = value;
  35. OnPropertyChanged("SelectedProduct");
  36. if (value != null)
  37. CanModify = true;
  38. else
  39. CanModify = false;
  40. RaiseCanExecute();
  41. }
  42. }
  43.  
  44. private List<tb_product> _products;
  45. public List<tb_product> Products
  46. {
  47. get
  48. {
  49. return _products;
  50. }
  51. set
  52. {
  53. _products = value;
  54. OnPropertyChanged("Products");
  55. }
  56. }
  57.  
  58. protected override void LoadData()
  59. {
  60. if (TreeVM.SelectedModel != null && !string.IsNullOrEmpty(TreeVM.SelectedModel.ID))
  61. Products = XDBContext.tb_product.Where(p => p.ClassifyID == TreeVM.SelectedModel.ID).AsNoTracking().ToList();
  62. else
  63. Products = XDBContext.tb_product.AsNoTracking().ToList();
  64. }
  65.  
  66. }
  1.   public class ClassifyTreeVM : ViewModelBase
  2. {
  3. public ClassifyTreeVM()
  4. {
  5. LoadData();
  6. }
  7.  
  8. private BindingList<TB_ClassifyTreeModel> _classifyModels;
  9. public BindingList<TB_ClassifyTreeModel> ClassifyModels
  10. {
  11. get
  12. {
  13. return _classifyModels;
  14. }
  15. set
  16. {
  17. _classifyModels = value;
  18. OnPropertyChanged("ClassifyModels");
  19. }
  20. }
  21.  
  22. public event EventHandler SelectedChanged;
  23.  
  24. private TB_ClassifyTreeModel _selectedModel;
  25. public TB_ClassifyTreeModel SelectedModel
  26. {
  27. get
  28. {
  29. return _selectedModel;
  30. }
  31. set
  32. {
  33. _selectedModel = value;
  34. OnPropertyChanged("SelectedModeld");
  35. if (SelectedChanged != null)
  36. SelectedChanged(SelectedModel, null);
  37. }
  38. }
  39.  
  40. protected override void LoadData()
  41. {
  42. ClassifyModels = new BindingList<TB_ClassifyTreeModel>();
  43. ClassifyModels.Add(new TB_ClassifyTreeModel(XDBContext)
  44. {
  45. ClassifyName = "All",
  46. ID = string.Empty
  47. });
  48. }
  49. }

  关于主从结构编辑的保存,UI绑定就是一个主表model(包含从表集合),没什么特别的。只是在保存的时候一起保存从表信息即可(从表中可能有增删改,具体如何操作取决于数据操作层,数据少懒惰点的做法可以一股脑先将相关从表记录全删掉然后添加,这样就不用区分哪些记录是删除的、哪些是修改的及哪些是新添加的;通常有时候会在model中设计一个状态属性,以方便区分model的状态)

wpf企业应用之主从结构列表的更多相关文章

  1. wpf企业应用之SelectButton(用于列表页之类的选择)

    在企业级应用中,通常我们会遇到这样的需求,需要点击一个按钮选择列表中的一项或者多项,然后将结果显示到按钮中.这里我给自己的控件命名为SelectButton,具体效果见 wpf企业级开发中的几种常见业 ...

  2. WPF如何用TreeView制作好友列表、播放列表

    WPF如何用TreeView制作好友列表.播放列表 前言 TreeView这个控件对于我来说是用得比较多的,以前做的小聊天软件(好友列表).音乐播放器(播放列表).类库展示器(树形类结构)等都用的是T ...

  3. Angular2.js——主从结构

    学习这一篇的内容,还回到我们快速起步的应用上来. 主从结构,我们想要做一个英雄的列表,我们希望用户在列表中选中一个英雄,然后这个被选中的英雄出现在详情视图中.主视图是英雄列表,从视图则是被选中英雄的详 ...

  4. WPF如何用TreeView制作好友列表、播放列表(转)

    WPF如何用TreeView制作好友列表.播放列表 前言 TreeView这个控件对于我来说是用得比较多的,以前做的小聊天软件(好友列表).音乐播放器(播放列表).类库展示器(树形类结构)等都用的是T ...

  5. DWZ主从结构计算

    最终效果图: 首先我们需要修改一下主从结构的源码dwz.database.js,如下: function tdHtml(field){ var html='',suffix=''; if(field. ...

  6. MySql5.5以上版本设置主从结构的例子

    为了实现读写分离,一般都需要先设置好mysql的主从结构,网上现有的mysql配置大都基于低版本,在5.5以上版本无法配置成功,所以参考了官方文档,写了这篇笔记. *主要参考Mysql 5.6的官方文 ...

  7. WPF - Group分组对ListBox等列表样式的约束

    原文:WPF - Group分组对ListBox等列表样式的约束 在做WPF主题支持时,出现一个分组引起的莫名错误,可是折腾了我一番.在没有使用样式时,列表分组很正常,使用了别人写的ListBox列表 ...

  8. 为 WPF 程序添加 Windows 跳转列表的支持

    原文:为 WPF 程序添加 Windows 跳转列表的支持 Windows 跳转列表是自 Windows 7 时代就带来的功能,这一功能是跟随 Windows 7 的任务栏而发布的.当时应用程序要想用 ...

  9. Redis主从结构主节点执行写入后wait命令对性能的影响

    这里的Redis主从结构可以是简单的主从,sentinel,redis cluster中的主从等. wait命令的作用:此命令将阻塞当前客户端,直到当前Session连接(主节点上)所有的写命令都被传 ...

随机推荐

  1. 对web标准的理解,以及对w3c组织的认识

    (1)web标准规范要求,书写标签必须闭合.标签小写.不乱嵌套,可提高搜索机器人对网页内容的搜索几率.--- SEO(2)建议使用外链css和js脚本,从而达到结构与行为.结构与表现的分离,提高页面的 ...

  2. 浅析XSS与XSSI异同

    浅析XSS与XSSI异同 这篇文章主要介绍了XSS与XSSI异同,跨站脚本(XSS)和跨站脚本包含(XSSI)之间的区别是什么?防御方法有什么不同?感兴趣的小伙伴们可以参考一下 Michael Cob ...

  3. 曹冲称象小游戏pygame实现

    #!/usr/bin/env python # -*- coding: UTF-8 -*- import pygame from pygame.locals import * from sys imp ...

  4. COM组件服务访问权限

    解决办法 :添加ASP.NET权限访问COM组件服务. IIS 5 上为 {MACHINE}\ASPNET IIS 6 和 IIS 7 上为网络服务:NETWORK SERVICE IIS 7.5 上 ...

  5. 大数据系列之分布式大数据查询引擎Presto

    关于presto部署及详细介绍请参考官方链接 http://prestodb-china.com PRESTO是什么? Presto是一个开源的分布式SQL查询引擎,适用于交互式分析查询,数据量支持G ...

  6. 006_Mac下sublime text 的“package control”安装,sublimepackage

    Mac下sublime text 的“package control”安装,sublimepackage 小伙伴们好,我根据昨晚的经历写一个小总结:关于“Mac下sublime text 的“pack ...

  7. Nginx实现代理和用户验证

    1.下载Nginx 首先去官网http://nginx.org/en/download.html下载需要的版本即可,无需安装,只需要打开nginx.exe文件,nginx.exe的服务就开启了.打开h ...

  8. vue+vuex+axios+echarts画一个动态更新的中国地图

    一. 生成项目及安装插件 # 安装vue-cli npm install vue-cli -g # 初始化项目 vue init webpack china-map # 切到目录下 cd china- ...

  9. java基础76 web服务器之Tomcat服务器

    (注:本文是以“压缩版Tomcat”为例,展开描述的) 一.Tomcat服务器的介绍 1.服务器 1.1.服务器的种类 从物理上讲:服务器就是一台pc机器.至少8核/8G以上.内存至少用T来计算.宽带 ...

  10. 《Javascript启示录》要点汇总

    前言:本文是阅读<Javascript启示录>后的一个读书笔记,对本书的要点进行了一个归纳,不是原创内容哦.要想详细了解相关内容,请阅读原书. 对象是由存储值的已命名属性组成的. Java ...