WPF、Caliburn.Micro 和 Dapper 组合框

WPF, Caliburn.Micro and Dapper ComboBoxes

我只是 WPF、Caliburn.Micro 和 Dapper 的新手。我有三个组合框:第一个是区域,第二个是特定选定区域的省份,第三个是特定选定省份的城市。 What I want to achieve is that when I selected a particular region it will display all the provinces in that region, the same with the province combo box, when selected it will display all the cities associated with that province.这可以用一种方法完成吗?到目前为止,这是我的代码。

数据访问

public List<RegionModel> GetRegion_All()
    {
        List<RegionModel> output;

        using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(GlobalConfig.CnnString(db)))
        {
            output = connection.Query<RegionModel>("dbo.spRegion_GetAll").ToList();
            var p = new DynamicParameters();


            foreach (RegionModel region in output)
            {
                p = new DynamicParameters();
                p.Add("@RegionId", region.Id);
                region.Provinces = connection.Query<ProvinceModel>("dbo.spProvince_ByRegion", p, commandType: CommandType.StoredProcedure).ToList();


                foreach (ProvinceModel province in region.Provinces)
                {
                    p = new DynamicParameters();
                    p.Add("@ProvinceId", province.Id);
                    region.Cities = connection.Query<CityModel>("dbo.spCity_ByProvince", p, commandType: CommandType.StoredProcedure).ToList();
                }
            }
        }
           return output;
    }

型号

  public class RegionModel
{
    public int Id { get; set; }
    public string Region { get; set; }
    public string RegionName { get; set; }
    public List<ProvinceModel> Provinces { get; set; } = new List<ProvinceModel>();
    public List<CityModel> Cities { get; set; } = new List<CityModel>();
    public List<BarangayModel> Barangays { get; set; } = new List<BarangayModel>();
}

 public class ProvinceModel
{
    public int Id { get; set; }
    public string Province { get; set; }
    public int RegionId { get; set; }

}

  public class CityModel
{
    public int Id { get; set; }
    public string City { get; set; }
    public int ProvinceId { get; set; }
    public int ZipCode { get; set; }
}

视图模型

 public class ShellViewModel : Screen
{
    private BindableCollection<RegionModel> _region;
    private RegionModel _selectedRegion;
    private ProvinceModel _selectedProvince;

    public ShellViewModel()
    {
        GlobalConfig.InitializeConnections(DatabaseType.Sql);
        Region = new BindableCollection<RegionModel>(GlobalConfig.Connection.GetRegion_All());
    }

    public BindableCollection<RegionModel> Region
    {
        get { return _region; }
        set
        {
            _region = value;
        }
   }

    public RegionModel SelectedRegion
    {
        get { return _selectedRegion; }
        set
        {
            _selectedRegion = value;
            NotifyOfPropertyChange(() => SelectedRegion);
        }
    }

    public ProvinceModel SelectedProvince
    {
        get { return _selectedProvince; }
        set
        {
            _selectedProvince = value;
            NotifyOfPropertyChange(() => SelectedRegion);
        }
    }

查看

 <Window x:Class="WPFUI.Views.ShellView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WPFUI.Views"
    mc:Ignorable="d" WindowStartupLocation="CenterScreen"
    Title="ShellView" Height="450" Width="800">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto" />
        <RowDefinition Height="auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <ComboBox Grid.Row="0" x:Name="Region" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding RegionName}" />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>


    <ComboBox Grid.Row="1" x:Name="SelectedRegion_Provinces" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Province}" />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>


    <ComboBox Grid.Row="2" x:Name="SelectedRegion_Cities" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding City}" />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

我的大部分代码想法都来自我在 youtube 上找到的教程,因为很难找到 WPF、Caliburn.Micro 和 Dapper 的参考资料和材料。请耐心等待我的代码:)

你大错特错,没有使用Caliburn的威力

wpf 定义:

对于 Caliburn,如果您为组合框指定名称 Region,它会等待具有相同名称 (Region) 的 bindableCollection,并且 SelectedItem 被命名为 SelectedRegion (see name convention with Caliburn)。所以我选择 Region, Province & City

在不同的模型中,我重命名了所有字符串 RegionName、ProvinceName 和 CityName。

    <ComboBox Grid.Row="0" x:Name="Region" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding RegionName}" />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>


    <ComboBox Grid.Row="1" x:Name="Province" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding ProvinceName}" />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>


    <ComboBox Grid.Row="2" x:Name="City" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding CityName}" />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

那么,我修改了你的class定义:

public class RegionModel:PropertyChangedBase
{
    public int Id { get; set; }
    public string Region { get; set; }
    public string RegionName { get; set; }
    // each Region has its Provinces
    public List<ProvinceModel> Provinces { get; set; } = new List<ProvinceModel>();
}

public class ProvinceModel:PropertyChangedBase
{
    public int Id { get; set; }
    public string ProvinceName { get; set; }
    public int RegionId { get; set; }
    // each Province has its Cities
    public List<CityModel> Cities { get; set; } = new List<CityModel>();
}

public class CityModel:PropertyChangedBase
{
    public int Id { get; set; }
    public string CityName { get; set; }
    public int ProvinceId { get; set; }
    public int ZipCode { get; set; }
}

然后在 ViewModel 中添加不同的 BindableCollection Region、Province & City 不要忘记添加

using Caliburn.Micro;

在使用定义中。然后添加选定的定义

public class ShellViewModel : Screen
{
    private RegionModel selectedRegion;
    private ProvinceModel selectedProvince;
    private CityModel selectedCity;
    private BindableCollection<RegionModel> _region;
    private BindableCollection<ProvinceModel> _province;
    private BindableCollection<CityModel> _city;
    public BindableCollection<RegionModel> Region
    {
        get { return _region; }
        set
        {
            _region = value;
            NotifyOfPropertyChange(() => Region);
        }
    }
    public BindableCollection<ProvinceModel> Province
    {
        get { return _province; }
        set
        {
            _province = value;
            NotifyOfPropertyChange(() => Province);
        }
    }
    public BindableCollection<CityModel> City
    {
        get { return _city; }
        set
        {
            _city = value;
            NotifyOfPropertyChange(() => City);
        }
    }

    public RegionModel SelectedRegion
    {
        get { return selectedRegion; }

        set
        {
            selectedRegion = value;
            NotifyOfPropertyChange(() => SelectedRegion);
            Province.Clear();
            Province.AddRange(selectedRegion.Provinces);
            NotifyOfPropertyChange(() => Province);
        }
    }
    public ProvinceModel SelectedProvince
    {
        get { return selectedProvince; }

        set
        {
            selectedProvince = value;
            NotifyOfPropertyChange(() => SelectedProvince);
            City.Clear();
            City.AddRange(selectedProvince.Cities);
            NotifyOfPropertyChange(() => City);
        }
    }
    public CityModel SelectedCity
    {
        get { return selectedCity; }

        set
        {
            selectedCity = value;
            NotifyOfPropertyChange(() => SelectedCity);
        }
    }


    public ShellViewModel()
   {
        // to DO INITIALIZE Regions
        //       
        Province = new BindableCollection<ProvinceModel>();
        City = new BindableCollection<CityModel>();
        Region = new BindableCollection<RegionModel>(Regions);
   }

并且您有一个功能示例

每次你 select 一个地区,相关的省份被加载,如果你 select 一个省份为相关的城市