WPF入门教程系列二十九 ——DataGrid使用示例MVVM模式(7)
阅读原文时间:2023年08月21日阅读:1

WPF入门教程系列目录

WPF入门教程系列二——Application介绍

WPF入门教程系列三——Application介绍(续)

WPF入门教程系列四——Dispatcher介绍

WPF入门教程系列五——Window 介绍

WPF入门教程系列十一——依赖属性(一)

WPF入门教程系列十五——WPF中的数据绑定(一)

接上文WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式(6)

13.通过Command指令,传递了下拉框所选择的省份,datagrid自动显示相应省份的城市信息,但是以上示例中有一个Bug,就是下拉框中绑定的数据无法显示。

这是由于DataGridComboBoxColumn若要填充下拉列表,请先使用以下选项之一设置 ItemsSource 属性 ComboBox :

1)静态资源。 使用StaticResource 标记扩展。

2)x:Static 代码实体。 使用x:Static 标记扩展。

3)类型的内联集合 ComboBoxItem 。

14.比较适合的绑定方式是  2)x:Static 代码实体。 使用x:Static 标记扩展需要添加相应的命名空间。在Visual Studio 2022中打开MainWindows.xmal文件,并在文件的开头添加如下命名空间。

xmlns:v="clr-namespace:WpfGridDemo.NET7.ViewModel"

15. 在Visual Studio 2022中打开MainWindows.xmal文件。对DataGridComboBoxColumn的ItemsSource进行了数据绑定。具体代码如下:

16.在Visual Studio 2022的解决方案资源管理器中,找到MainWindowVM.cs文件,将GridCityList属性改为静态属性,用于绑定DataGridComboBoxColumn的ItemsSource。具体如下代码:

    private static ObservableCollection<City> cityList;  
    public static ObservableCollection<City> GridCityList  
    {

        get { return cityList; }  
        set  
        {

            cityList = value;  
            new ViewModelBase().RaisePropertyChanged("GridCityList");  
        }

    }

17.在Visual Studio 2022中按F5键,启动WPF应用程序。然后使用鼠标点击省份下拉框,能够看到,界面中DataGrid中的数据,随着下拉框的变化而随之变化,但是城市下拉框中却没有任何数据。看来绑定失效了。如下图。

18. 使用静态代码实体的方式,实现省市县联动失败了。又不想使用其他两种方式。在一阵猛于虎的搜索之后,发现一种实现方式。在Visual Studio 2022中打开MainWindows.xmal文件。对DataGridComboBoxColumn进行了数据绑定。具体代码如下:

19.在Visual Studio 2022的解决方案资源管理器中,找到MainWindowVM.cs文件,添加一个GridCity属性,用于绑定DataGridComboBoxColumn的ItemsSource。以下是属性代码,更完整的代码,请参见下面类的完整代码。

private ObservableCollection listCity;

    public ObservableCollection<City> GridCity  
    {

        get { return listCity; }  
        set  
        {  
            listCity = value;  
            RaisePropertyChanged("GridCity");  
        }  
    }

20.MainWindow.xmal的全部代码如下:

<Grid>  
    <Grid.RowDefinitions>  
        <RowDefinition Height="100"></RowDefinition>  
        <RowDefinition Height="\*"></RowDefinition>  
        <RowDefinition Height="25"></RowDefinition>  
    </Grid.RowDefinitions>  
    <WrapPanel Grid.Row="0" HorizontalAlignment="Left">  
        <ComboBox x:Name="cboProvince" DisplayMemberPath="Name" SelectedValuePath="Code" >  
            <be:Interaction.Triggers>  
                <be:EventTrigger EventName="SelectionChanged">  
                    <be:InvokeCommandAction Command="{Binding ProviceChangedAction}"  

CommandParameter="{Binding ElementName=cboProvince}"/>


    </WrapPanel>

    <DataGrid x:Name="gridArea" Grid.Row="1" ItemsSource="{Binding GridAreaList}"   

AutoGenerateColumns="False" HorizontalAlignment="Left" VerticalAlignment="Top"
SelectedItem="{Binding Path=AreaVM,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">

            <DataGridComboBoxColumn Header="城市(Style)" SelectedValuePath="Code"  

SelectedValueBinding="{Binding Path=CityCode,UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name" SelectedItemBinding="{x:Null}" Width="1*">

                <DataGridComboBoxColumn.EditingElementStyle>  
                    <Style TargetType="ComboBox">  
                        <Setter Property="ItemsSource"   

Value="{Binding Path=DataContext.GridCity,ElementName=gridArea}" />

                </DataGridComboBoxColumn.EditingElementStyle>  
                <DataGridComboBoxColumn.ElementStyle>  
                    <Style TargetType="ComboBox">  
                        <Setter Property="ItemsSource"   

Value="{Binding Path=DataContext.GridCity,ElementName=gridArea}" />

                </DataGridComboBoxColumn.ElementStyle>

            </DataGridComboBoxColumn>

            <DataGridTextColumn Header="县区镇" Width="\*"   

Binding="{Binding Name}" ClipboardContentBinding="{x:Null}"/>







21. MainWindowsVM类的完整代码,如下:

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.DirectoryServices.ActiveDirectory;

using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

using System.Windows.Input;
using WpfGridDemo.NET7.Entitys;

namespace WpfGridDemo.NET7.ViewModel
{

public class MainWindowVM: ViewModelBase  
{

    public MainWindowVM() {  
        cityList = new ObservableCollection<City>();

        areaList = new ObservableCollection<Area>();

        listCity = new ObservableCollection<City>();   

    }

    private Area m\_Area;

    /// <summary>  
    /// 县镇区数据  
    /// </summary>  
    public Area AreaVM

    {

        get { return m\_Area; }

        set { m\_Area = value; }

    }

    private string m\_Province\_Code;

    /// <summary>  
    /// 省--代码  
    /// </summary>

    public string ProvinceCode { get => m\_Province\_Code; set => m\_Province\_Code = value; }

    private ObservableCollection<Area> areaList;

     public ObservableCollection<Area> GridAreaList  
     {  
         get { return areaList; }

         set  
         {

            areaList = value;  
             RaisePropertyChanged("GridAreaList");

         }

    }

    private static ObservableCollection<City> cityList;

    public static ObservableCollection<City> GridCityList  
    {

        get { return cityList; }

        set  
        {  
            cityList = value;  
            new ViewModelBase().RaisePropertyChanged("GridCityList");  
        }  
    } 

    private ObservableCollection<City> listCity;

    public ObservableCollection<City> GridCity

    {  
        get { return listCity; }  
        set

        {  
            listCity = value;  
            RaisePropertyChanged("GridCity");  
        }

    }

    /// <summary>  
    /// 命令要执行的方法  
    /// </summary>  
    void SaveExecute()  
    {

        try  
        {

            GridDbContext db = new GridDbContext();  
            var list=db.Area.AsTracking().ToList();  
            Area modifyArea = list.Where(x=>x.Id==AreaVM.Id).FirstOrDefault();

            if (modifyArea != null)

            {

                modifyArea.Name = AreaVM.Name;

                modifyArea.Updated = DateTime.Now;

                db.SaveChanges();

            }  
        }  
        catch (Exception ex)  
        {  
            throw ex;  
        }  
    }

    /// <summary>  
    /// 命令是否可以执行  
    /// </summary>  
    /// <returns></returns>  
    bool CanSaveExecute()  
    {  
        return false;  
    }

    /// <summary>  
    /// 创建新命令  
    /// </summary>  
    public ICommand ClickSaveAction  
    {  
        get  
        {  
            return new Command.SaveCommand(SaveExecute, CanSaveExecute);  
        }

    }

    //combobox  
    /// <summary>  
    /// 命令要执行的方法  
    /// </summary>  
    void ProviceSelectionChangedExecute(object sender)  
    {  
        try  
        {

            if (sender is ComboBox)

            {

                ComboBox drp=sender as ComboBox;

                ProvinceCode=drp.SelectedValue.ToString();

                GridDbContext db = new GridDbContext();

                var list = db.City.AsTracking().ToList();

                List<City> citys = list.Where(x => x.ProvinceCode == ProvinceCode).ToList();

                var cityCodes = from city in citys

                                select city.Code;

                List<Area> areas = db.Area.AsTracking().ToList()  

.Where(x => cityCodes.Contains(x.CityCode)).ToList();
areaList.Clear();

                if (areas!=null)  
                {  
                    areas.ForEach((t) =>

                    { areaList.Add(t); }

                    );

                }  
                cityList.Clear();

                if (citys != null)

                {

                    citys.ForEach((t) =>

                    { cityList.Add(t); }

                    );  
                }  
                listCity.Clear();

                if (citys != null)

                {

                    citys.ForEach((t) =>

                    { listCity.Add(t); }

                    );

                }

            }

        }  
        catch (Exception ex)  
        {

            throw ex;  
        }  
    }

    /// <summary>  
    /// 命令是否可以执行  
    /// </summary>  
    /// <returns></returns>  
    bool CanSelectionChangedExecute()  
    {  
        return true;  
    }

    /// <summary>  
    /// 创建新命令  
    /// </summary>  
    public ICommand ProviceChangedAction  
    {

        get  
        {

            return new Command.ProvinceChangedCommand<object>(ProviceSelectionChangedExecute  

, CanSelectionChangedExecute);

        }  
    }  
}  

}

22.在Visual Studio 2022中按F5键,启动WPF应用程序。然后使用鼠标点击省份下拉框,能够看到,界面中DataGrid中的数据,随着下拉框的变化而随之变化,其中使用静态实体代码绑定的城市下拉框中却没有任何数据。使用使用非静态资源,在两个样式中绑定combobox的itemSource属性方式,效果有效。如下图。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章