• wpf企业应用之主从结构列表


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

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

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

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

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

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <HeaderedContentControl>
                <HeaderedContentControl.Header>
                    <DockPanel>
                        <TextBlock VerticalAlignment="Center" Text="{DynamicResource ProductClassify_Header_Classify}" DockPanel.Dock="Left"/>
                        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">
                            <Button Name="Button_RefreshClassify" Style="{StaticResource RefreshIconButton}" Content="{DynamicResource Common_Refresh}" Command="{Binding TreeVM.RefreshCommand}"/>
                        </StackPanel>
                    </DockPanel>
                </HeaderedContentControl.Header>
                <local:ClassifyTreeControl DataContext="{Binding TreeVM}"/>
            </HeaderedContentControl>
    
            <HeaderedContentControl Name="Header_Product" Grid.Column="1">
                <HeaderedContentControl.Header>
                    <DockPanel>
                        <TextBlock VerticalAlignment="Center" Text="{DynamicResource ProductList_Header_Product}" DockPanel.Dock="Left"/>
                        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">
                            <Button Name="Button_RefreshClassify2" Style="{StaticResource RefreshIconButton}" Content="{DynamicResource Common_Refresh}" Command="{Binding RefreshCommand}"/>
                            <Button Name="Button_AddProduct" Visibility="{Binding AddButtonVisibility}" IsEnabled="{Binding CanAdd}" Style="{StaticResource AddIconButton}" Content="{DynamicResource Common_Add}" Click="Button_AddProduct_Click"/>
                            <Button Name="Button_ModifyProduct" Visibility="{Binding ModifyButtonVisibility}" IsEnabled="{Binding CanModify}" Style="{StaticResource ModifyIconButton}" Content="{DynamicResource Common_Modify}" Click="Button_ModifyProduct_Click"/>
                            <Button Name="Button_DeleteProduct" Visibility="{Binding DeleteButtonVisibility}" Style="{StaticResource DeleteIconButton}" Content="{DynamicResource Common_Delete}" Command="{Binding DeleteCommand}"/>
                        </StackPanel>
                    </DockPanel>
                </HeaderedContentControl.Header>
                <DataGrid Name="DataGrid_Product" ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct}" SelectionMode="Single" AutoGenerateColumns="False" IsReadOnly="True">
                    <DataGrid.Columns>
                        <DataGridTextColumn Header="{DynamicResource Product_Num}" Binding="{Binding Num}" Width="120"/>
                        <DataGridTextColumn Header="{DynamicResource Product_Name_CH}" Binding="{Binding Name_CH}" Width="100"/>
                        <DataGridTextColumn Header="{DynamicResource Product_Name_EN}" Binding="{Binding Name_EN}" Width="100"/>
                        <DataGridTextColumn Header="{DynamicResource Product_Unit}" Binding="{Binding Unit}" Width="50"/>
                        <DataGridTextColumn Header="{DynamicResource Product_Weight}" Binding="{Binding Weight}" Width="100"/>
                        <DataGridTextColumn Header="{DynamicResource Product_Size}" Binding="{Binding Size}" Width="100"/>
                        <DataGridTemplateColumn Header="{DynamicResource Product_CanSale}">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox IsThreeState="False" IsChecked="{Binding CanSale}" IsEnabled="False" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" HorizontalAlignment="Center" Width="50"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Header="{DynamicResource Product_ReferencePrice}" Binding="{Binding ReferencePrice}" Width="100"/>
                        <DataGridTemplateColumn Header="{DynamicResource Product_StopProduction}">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox IsThreeState="False" IsChecked="{Binding StopProduction}" IsEnabled="False" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" HorizontalAlignment="Center" Width="50"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Header="{DynamicResource Product_MinSaleCount}" Binding="{Binding MinSaleCount}" Width="80"/>
                        <DataGridTextColumn Header="{DynamicResource Product_PackageCount}" Binding="{Binding PackageCount}" Width="80"/>
                        <DataGridTextColumn Header="{DynamicResource Product_Remark}" Binding="{Binding Remark}" Width="200"/>
                    </DataGrid.Columns>
                    <DataGrid.RowStyle>
                        <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
                            <Setter Property="ToolTip">
                                <Setter.Value>
                                    <Border Width="100" Height="100" BorderBrush="#FF7DB6D8" BorderThickness="1" Padding="1">
                                        <Border.Resources>
                                            <product:PicUrlConverter x:Key="urlConverter"/>
                                        </Border.Resources>
                                        <Image Source="{Binding ProductPic, Converter={StaticResource urlConverter}}"/>
                                    </Border>
                                </Setter.Value>
                            </Setter>
                            <EventSetter Event="MouseDoubleClick" Handler="Button_ModifyProduct_Click"/>
                        </Style>
                    </DataGrid.RowStyle>
                </DataGrid>
            </HeaderedContentControl>
        </Grid>

      ViewModel中相关代码

        public class ProductListVM : ViewModelBase
        {
            public ProductListVM()
            {
                LoadData();
                TreeVM.SelectedChanged += (s, e) =>
                {
                    LoadData();
                    if (TreeVM.SelectedModel != null && !string.IsNullOrEmpty(TreeVM.SelectedModel.ID))
                        CanAdd = true;
                    else
                        CanAdd = false;
                };
            }
    
            private ClassifyTreeVM _treeVM;
            public ClassifyTreeVM TreeVM
            {
                get
                {
                    return _treeVM ?? (_treeVM = new ClassifyTreeVM());
                }
            }
    
            private tb_product _selectedProduct;
            public tb_product SelectedProduct
            {
                get
                {
                    return _selectedProduct;
                }
                set
                {
                    _selectedProduct = value;
                    OnPropertyChanged("SelectedProduct");
                    if (value != null)
                        CanModify = true;
                    else
                        CanModify = false;
                    RaiseCanExecute();
                }
            }
    
            private List<tb_product> _products;
            public List<tb_product> Products
            {
                get
                {
                    return _products;
                }
                set
                {
                    _products = value;
                    OnPropertyChanged("Products");
                }
            }
    
            protected override void LoadData()
            {
                if (TreeVM.SelectedModel != null && !string.IsNullOrEmpty(TreeVM.SelectedModel.ID))
                    Products = XDBContext.tb_product.Where(p => p.ClassifyID == TreeVM.SelectedModel.ID).AsNoTracking().ToList();
                else
                    Products = XDBContext.tb_product.AsNoTracking().ToList();
            }
    
        }
      public class ClassifyTreeVM : ViewModelBase
        {
            public ClassifyTreeVM()
            {
                LoadData();
            }
    
            private BindingList<TB_ClassifyTreeModel> _classifyModels;
            public BindingList<TB_ClassifyTreeModel> ClassifyModels
            {
                get
                {
                    return _classifyModels;
                }
                set
                {
                    _classifyModels = value;
                    OnPropertyChanged("ClassifyModels");
                }
            }
    
            public event EventHandler SelectedChanged;
    
            private TB_ClassifyTreeModel _selectedModel;
            public TB_ClassifyTreeModel SelectedModel
            {
                get
                {
                    return _selectedModel;
                }
                set
                {
                    _selectedModel = value;
                    OnPropertyChanged("SelectedModeld");
                    if (SelectedChanged != null)
                        SelectedChanged(SelectedModel, null);
                }
            }
    
            protected override void LoadData()
            {
                ClassifyModels = new BindingList<TB_ClassifyTreeModel>();
                ClassifyModels.Add(new TB_ClassifyTreeModel(XDBContext)
                {
                    ClassifyName = "All",
                    ID = string.Empty
                });
            }
        }

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

  • 相关阅读:
    Codeforces 1111D(退背包、排列组合)
    Codeforces 1152D(dp)
    UVaLive6443(线段树)
    UVaLive6435(dp)
    POJ1741(点分治)
    Codeforces 161D(树形dp)
    BZOJ2595(状压dp)
    关于spring java.lang.IllegalArgumentException: Name for argument type [java.lang.String] 的错误
    FingerPrint Fuzzy Vault Matlab实践
    Mybatis的ResultMap的使用
  • 原文地址:https://www.cnblogs.com/Fuss/p/4093743.html
Copyright © 2020-2023  润新知