wpf企業應用之主從結構列表

  主從結構在企業級應用中至關常見,這裏結合個人例子談一下wpf中主從結構列表展現的經常使用作法,具體效果見 wpf企業級開發中的幾種常見業務場景html

  首先,Model有兩種,主表對應model(假設爲modelA),從表對應的model(假設爲modelB),兩種model分別用於綁定列表,就是普通列表的綁定。ide

  其次,因爲要實現聯動效果(即選擇主表中的一條記錄顯示從表的記錄),故而咱們的ViewModel裏面必須設計一個SelectedModelA用來綁定選中項,SelectedModelA變化時去更新modelB列表的數據源(一般SelectedModelA中會包含一個集合,不過我這裏因爲其餘緣由單獨弄了個集合,邏輯其實大同小異)。url

  下面是個人代碼,因爲夾雜着一些業務,僅供參考,其實讀者只需明白主表的選中項做爲從表UI的數據源便可。spa

  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中相關代碼code

    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的狀態)htm

相關文章
相關標籤/搜索