• WPF .netCore使用MVVM


    WPF MVVM模式一直没怎么用过,.net5正式版就要出来了,趁这个时间看看各个微软的前后端.netCore的功能,使用.netCore下WPF实现一个简单的从数据库读取数据显示功能,

    示例主要用到了按钮,编辑框,树控件,列表控件, 代码东拼西凑的,只贴几个片段。

    1、XAML

    <Page x:Class="NEasyCode.PageDataBase"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
          xmlns:local="clr-namespace:NEasyCode"
          mc:Ignorable="d" 
          d:DesignHeight="450" d:DesignWidth="800"
          Title="PageDataBase"
          >
        <Page.DataContext>
            <local:DataBaseViewModel />
        </Page.DataContext>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="300" />
                <ColumnDefinition Width="5" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <DockPanel >
                <Grid DockPanel.Dock="Top">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="50" />
                    </Grid.ColumnDefinitions>
                    <Label Name="LabelFilter" Grid.Column="0">表名过滤:</Label>
                    <TextBox Margin="0,0,0,0"  Grid.Column="1"  Name="TextFilter" Text="{Binding  Path=SearchText, Mode=TwoWay}"/>
                    <Button Name="ButtonRefresh" Content="刷新"  Grid.Column="2" Width="40"  DockPanel.Dock="Right" Command="{Binding Path=QueryCommand}"></Button>
                </Grid>
                <TreeView Margin="0,0,0,0" 
                          Name="TreeDataBase"
                          ScrollViewer.VerticalScrollBarVisibility="Auto" 
                          ItemsSource="{Binding TreeViewItems}">
                </TreeView>
            </DockPanel>
    
            <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Left" />
            <DockPanel  Grid.Column="2" >
                <DataGrid Name="TableProp" ItemsSource="{Binding Path=TableInfoList}">
                    <DataGrid.Columns>
                        <DataGridTextColumn  Header="编号" Width="90" Binding="{Binding ColumnId}"/>
                        <DataGridTextColumn  Header="列名" Width="90" Binding="{Binding ColumnName}"/>
                        <DataGridTextColumn  Header="主键" Width="90" Binding="{Binding ColumnIsPrimaryKey}"/>
                        <DataGridTextColumn  Header="标识列" Width="90" Binding="{Binding ColumnIsIdentity}"/>
                        <DataGridTextColumn  Header="列类型" Width="90" Binding="{Binding ColumnType}"/>
                        <DataGridTextColumn  Header="长度" Width="90" Binding="{Binding ColumnLength}"/>
                        <DataGridTextColumn  Header="精度" Width="90" Binding="{Binding ColumnPrecision}"/>
                        <DataGridTextColumn  Header="小数点" Width="90" Binding="{Binding ColumnScale}"/>
                        <DataGridTextColumn  Header="允许空" Width="90" Binding="{Binding ColumnIsNullAble}"/>
                        <DataGridTextColumn  Header="默认值" Width="90" Binding="{Binding ColumnDefaultValue}"/>
                        <DataGridTextColumn  Header="列描述" Width="90" Binding="{Binding ColumnDesc}"/>
                        <DataGridTextColumn  Header="索引" Width="90" Binding="{Binding ColumnIndexName}"/>
                        <DataGridTextColumn  Header="排序" Width="90" Binding="{Binding ColumnIndexSort}"/>
                    </DataGrid.Columns>
                </DataGrid >
                <DataGrid Name="TableData" ItemsSource="{Binding}">
                    <DataGrid.Columns>
                    </DataGrid.Columns>
                </DataGrid>
            </DockPanel>
            
        </Grid>
    </Page>
    

    2、DataBaseModel.cs

    using NEasyCode.Entity;
    using NEasyCode.Util;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Text;
    using System.Windows.Controls;
    using System.Windows.Input;
    
    namespace NEasyCode
    {
        public class DataBaseViewModel : INotifyPropertyChanged
        {
            #region Fields
            private string _searchText;
            private ObservableCollection<TableInfo> _resultList;
            #endregion
    
            #region Properties
            private ObservableCollection<TableInfo> tableInfoList;
            public ObservableCollection<TableInfo> TableInfoList 
            { 
                get {
                    return tableInfoList;
                } 
                set
                {
                    tableInfoList = value;
                    RaisePropertyChanged("TableInfoList");
                } 
            }
            public ObservableCollection<string> TableList { get; set; } = new ObservableCollection<string>();
            public ObservableCollection<TreeViewItem> TreeViewItems { get; set; } = new ObservableCollection<TreeViewItem>();
            // 查询关键字
            public string SearchText
            {
                get { return _searchText; }
                set
                {
                    _searchText = value;
                    RaisePropertyChanged("SearchText");
                }
            }
            public ICommand QueryCommand
            {
                get { return new QueryCommand(SearchTable, CanSearching); }
            }
    
    
            #endregion
    
            #region Construction
            public DataBaseViewModel()
            {
                SearchTable();
                ViewTableInfo("dghr_userinfo");
            }
    
    
            #endregion
            
            #region Command Handler
            /// <summary>
            /// 查看表信息
            /// </summary>
            /// <param name="tableName"></param>
            public void ViewTableInfo(string tableName)
            {
                //TableInfoList.Clear();
                TableInfoList = DbUtil.GetTableProp(tableName).ToObservableCollection();
                //_resultList = TableInfoList;
            }
            /// <summary>
            /// 查找表
            /// </summary>
            public void SearchTable()
            {
                TableList.Clear();
                var tableList= DbUtil.GetAllDataBase().ToObservableCollection();
                if (string.IsNullOrWhiteSpace(SearchText))
                {
                    TableList = tableList;
                }
                else
                {
                   
                    foreach (string p in tableList)
                    {
                        if (p.Contains(SearchText))
                        {
                            TableList.Add(p);
                        }
                    }
                }
                TreeViewItems.Clear();
                for (int i = 0; i < TableList.Count; i++)
                {
                    TreeViewItem item = new TreeViewItem();
                    item.Header = TableList[i];
                    item.Selected += Item_Selected;
                    item.MouseDoubleClick += Item_MouseDoubleClick;
                    
                    TreeViewItems.Add(item);
                }
            }
    
            private void Item_Selected(object sender, System.Windows.RoutedEventArgs e)
            {
                var v= ((TreeViewItem)(e.Source)).Header.ToString();
                ViewTableInfo(v);
            }
    
            private void Item_MouseDoubleClick(object sender, MouseButtonEventArgs e)
            {
                //ViewTableInfo(e.ToString)
            }
    
            public bool CanSearching()
            {
                return true;
            }
    
    
            #endregion
    
            #region INotifyPropertyChanged Members
    
            public event PropertyChangedEventHandler PropertyChanged;
    
    
            #endregion
    
            #region Methods
            private void RaisePropertyChanged(string propertyName)
            {
                // take a copy to prevent thread issues
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
            #endregion
        }
    
    }
    

    3、Command

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Input;
    
    namespace NEasyCode
    {
        class QueryCommand : ICommand
        {
            #region Fields
            private Action _execute;
            private Func<bool> _canExecute;
            #endregion 
    
            public QueryCommand(Action execute)
                : this(execute, null)
            {
            }
            public QueryCommand(Action execute, Func<bool> canExecute)
            {
                if (execute == null)
                    throw new ArgumentNullException("execute");
                _execute = execute;
                _canExecute = canExecute;
            }
    
            #region ICommand Member
    
            public event EventHandler CanExecuteChanged
            {
                add
                {
                    if (_canExecute != null)
                    {
                        CommandManager.RequerySuggested += value;
    
                    }
                }
                remove
                {
                    if (_canExecute != null)
                    {
                        CommandManager.RequerySuggested -= value;
    
                    }
                }
            }
    
            public bool CanExecute(object parameter)
            {
                return _canExecute == null ? true : _canExecute();
            }
    
            public void Execute(object parameter)
            {
                _execute();
            }
            #endregion
        }
    }
    

    4、TableInfo实体

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace NEasyCode.Entity
    {
        public class TableInfo
        {
            public string TableName { get; set; }
            public string TableDesc { get; set; }
            public int ColumnId { get; set; }
            public string ColumnName { get; set; }
            public bool ColumnIsPrimaryKey { get; set; }
            public bool ColumnIsIdentity { get; set; }
            public string ColumnType { get; set; }
            public int ColumnLength { get; set; }
            public int ColumnPrecision { get; set; }
            public int ColumnScale { get; set; }
            public bool ColumnIsNullAble { get; set; }
            public string ColumnDefaultValue { get; set; }
            public string ColumnDesc { get; set; }
            public string ColumnIndexName { get; set; }
            public string ColumnIndexSort { get; set; }
            public DateTime ColumnCreateDate { get; set; }
            public DateTime ColumnModifyDate { get; set; }
        }
    }
    

    5、运行效果

    6、有几点问题,研究的不深,可能因为使用的不算完全纯正的mvvm的原因,有几点疑惑。

    6.1 树控件数据源不需要调用RaisePropertyChanged,但是DataGrid需要,没有搞明白为什么这样。

    6.2 树控件的绑定事件按网上的无法使用,.netCore下无法引入NuGet下的System.Windows.Interactivity,其它引入方式未试验,直接使用事件绑定的方式了。

    通过Command绑定事件
    
    在项目中引用 System.Windows.Interactivity.WPF(简单来说该插件可以将页面控件的Event转为ViewModel中的Command)
    在窗体中添加引用
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    绑定Command到SelectedItemChanged事件
    <TreeView x:Name="treeView" ItemsSource="{Binding TypeList}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectedItemChanged">
            <i:InvokeCommandAction Command="{Binding SelectItemChangeCommand}"
                   CommandParameter="{Binding ElementName=treeView,Path=SelectedItem}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    </TreeView> 

    后续测试:在.net5 预览版下是可以的,.netCore下不行,

     

     7、在xp下无法运行,传家项目没有必须升级的需求还是用.net4.0吧。

      

      

      

  • 相关阅读:
    MySql跨服务器备份数据库
    html特殊字符过滤
    PHP简单去掉文件里面的空行和重复行
    汉字转拼音首字母缩写
    php 时间配置
    兼容ie6、ie7和firefox的div控制最小高度又自适高度的设置
    JBoss AS7:Timeout deploying JBoss applications
    中国经纬度范围
    CSS 架构
    linux 下 rpm 安装mysql
  • 原文地址:https://www.cnblogs.com/zhaogaojian/p/13882106.html
Copyright © 2020-2023  润新知