WPF, Caliburn.Micro и Dapper ComboBox - PullRequest
       39

WPF, Caliburn.Micro и Dapper ComboBox

1 голос
/ 26 апреля 2020

Я новичок в WPF, Caliburn.Micro и Dapper. У меня есть три поля со списком: первый - для региона, второй - для провинций в определенном выбранном регионе, а третий - города в определенной выбранной провинции. Чего я хочу добиться, так это того, чтобы при выборе определенного региона отображались все провинции в этом регионе, то же самое, что и в поле со списком провинций, а при выборе отображались все города, связанные с этой провинцией. Можно ли это сделать одним способом? Вот мой код.

DataAccess

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; }
}

ViewModel

 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 очень трудно найти. Пожалуйста, будьте терпеливы с моим кодом:)

1 Ответ

0 голосов
/ 26 апреля 2020

У вас много ошибок, и вы не используете мощь Caliburn

Определение wpf:

с Caliburn, если вы дадите имя Region для выпадающего списка, он ожидает bindableCollection с тем же именем ( Region) и SelectedItem называется SelectedRegion ( см. Соглашение об именах с 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>

Затем я изменил определение вашего класса:

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, провинцию и город. Не забудьте добавить

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);
   }

, и вы получите функциональный образец

Каждый раз, когда вы выбираете регион, загружаются связанные провинции, и то же самое, если вы выбираете провинцию для связанных городов

...