在最近的工作中遇到很多,类似这种layUI风格的Combox:

  因为WPF原本的控件,并不具备这种功能,尝试重写Combox的模板,发现无从下手。

  于是尝试从多个控件组合来实现这个功能。

  这里使用了Popup 来存放数据,发现还不错。

  将popup分为三列,每个列的列宽设置位自动,当点击其中一个选项的时候,检索所选,根据字典查到数据,再加载其他列。

  即可实现这种效果

  代码如下:

  UI:

<Button x:Name="btn1"
Height="54"
Margin="0,10,0,0"
Click="Button_Click">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border
Background="Transparent"
CornerRadius="15"
BorderBrush="#6B778D"
BorderThickness="1">
<Grid>
<TextBlock
Text="▼"
Margin="0,0,5,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Foreground="White"
FontSize="20" />
<TextBlock
Text="{Binding Shell6PageModel.DetailedAddress}"
Margin="10,0,0,0"
VerticalAlignment="Center"
Foreground="White"
FontSize="32" />
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Popup x:Name="pop1"
Width="{Binding ElementName=btn1, Path=ActualWidth}"
Height="260"
AllowsTransparency="True"
IsOpen="False"
Placement="Bottom"
PlacementTarget="{Binding ElementName=btn1}"
PopupAnimation="Slide"
StaysOpen="False">
<Grid>
<Border
Background="Gray"
Opacity="0.9"
BorderBrush="Gray"
BorderThickness="1"
CornerRadius="8" /> <Border>
<Grid HorizontalAlignment="Center">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> <Grid Grid.Column="0">
<ListBox
ItemsSource="{Binding Countries}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
BorderThickness="0"> <ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Border x:Name="bord1" />
<ContentPresenter />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bord1" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle> <ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding DetailedCountry}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Shell6Page}}, Path=DataContext.countryCommand}"
CommandParameter="{Binding}"
Width="100"
Height="35"
Margin="0,5,0,5"
VerticalAlignment="Center"
Foreground="White"
FontSize="36"
GroupName="0" />
</DataTemplate>
</ListBox.ItemTemplate> </ListBox> </Grid> <Grid Grid.Column="1">
<ListBox
ItemsSource="{Binding Shengs}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
BorderThickness="0"> <ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Border x:Name="bord1" />
<ContentPresenter VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bord1" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle> <ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding DetailedSheng}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Shell6Page}}, Path=DataContext.shengCommand}"
CommandParameter="{Binding}"
Width="100"
Height="35"
Margin="0,5,0,5"
VerticalAlignment="Center"
Foreground="White"
FontSize="36"
GroupName="1" />
</DataTemplate>
</ListBox.ItemTemplate> </ListBox> </Grid> <Grid Grid.Column="2">
<ListBox
ItemsSource="{Binding Cities}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
BorderThickness="0">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}"> <Grid>
<Border x:Name="bord1" />
<ContentPresenter />
</Grid> <ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bord1" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle> <ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding DetailedCity}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Shell6Page}}, Path=DataContext.cityCommand}"
CommandParameter="{Binding}"
Width="100"
Height="35"
Margin="0,5,0,5"
VerticalAlignment="Center"
Foreground="White"
FontSize="36"
GroupName="2" />
</DataTemplate>
</ListBox.ItemTemplate> </ListBox> </Grid> <Grid Grid.Column="3">
<ListBox
ItemsSource="{Binding Areas}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
BorderThickness="0">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}"> <Grid>
<Border x:Name="bord1" />
<ContentPresenter />
</Grid> <ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bord1" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle> <ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding DetailedArea}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Shell6Page}}, Path=DataContext.areaCommand}"
CommandParameter="{Binding}"
Width="100"
Height="35"
Margin="0,5,0,5"
Foreground="White"
FontSize="36"
Click="RadioButton_Click"
GroupName="3" />
</DataTemplate>
</ListBox.ItemTemplate> </ListBox> </Grid> </Grid> </Grid> </Border> </Grid>
</Popup>

Model:

public class Shell6PageModel:ViewModelBase
{
private string detailedAddress;
/// <summary>
/// 详细地址
/// </summary>
public string DetailedAddress
{
get { return detailedAddress; }
set
{
detailedAddress = value; }
} private string area;
/// <summary>
/// 所在地区
/// </summary>
public string Area
{
get { return area; }
set { area = value; }
}
}

ViewModel:

public class Shell6PageViewModel : ViewModelBase
{
Dictionary<string, string> AddressCity = new Dictionary<string, string>();
Dictionary<string, string> AddressArea = new Dictionary<string, string>();
Dictionary<string, string> AddressSheng = new Dictionary<string, string>();
Dictionary<string, string> AddressCountry = new Dictionary<string, string>();
string[] ad; public Shell6PageViewModel()
{
countryCommand = new RelayCommand<Country>(t => GetCountry(t));
shengCommand = new RelayCommand<Sheng>(t => GetSheng(t));
cityCommand = new RelayCommand<City>(t => GetCity(t));
areaCommand = new RelayCommand<Area>(t => GetArea(t)); Shell6PageModel = new Shell6PageModel()
{
Area = EAppEnvironment.informationInfo.Area, DetailedAddress = EAppEnvironment.informationInfo.DetailedAddress };
InitDictionary();
} private void GetArea(Area t)
{
ad[3] = t.DetailedArea;
Shell6PageModel.DetailedAddress = "";
foreach (var item in ad)
{
Shell6PageModel.DetailedAddress += item;
} } private void GetCity(City t)
{
Areas.Clear(); ad[2] = t.DetailedCity;
Shell6PageModel.DetailedAddress = "";
foreach (var item in ad)
{
Shell6PageModel.DetailedAddress += item;
} foreach (var item in AddressArea)
{
if (t.DetailedCity == item.Value)
{
Areas.Add(new Area { DetailedArea = item.Key }); }
}
} private void GetSheng(Sheng t)
{
Cities.Clear();
Areas.Clear();
ad[1] = t.DetailedSheng;
Shell6PageModel.DetailedAddress = "";
foreach (var item in ad)
{
Shell6PageModel.DetailedAddress += item;
}
foreach (var item in AddressCity)
{
if (t.DetailedSheng == item.Value)
{
Cities.Add(new City() { DetailedCity = item.Key }); }
} } private void GetCountry(Country t)
{
Shengs.Clear();
Cities.Clear();
Areas.Clear();
ad = null;
ad = new string[4];
ad[0] = t.DetailedCountry;
Shell6PageModel.DetailedAddress = "";
foreach (var item in ad)
{
Shell6PageModel.DetailedAddress += item;
}
foreach (var item in AddressSheng)
{
if (t.DetailedCountry == item.Value)
{
Shengs.Add(new Sheng() { DetailedSheng = item.Key });
}
}
} private Shell6PageModel shell6PageModel; public Shell6PageModel Shell6PageModel
{
get { return shell6PageModel; }
set { shell6PageModel = value; RaisePropertyChanged(); }
} public RelayCommand<Sheng> shengCommand { get; set; } public RelayCommand<Country> countryCommand { get; set; } public RelayCommand<City> cityCommand { get; set; }
public RelayCommand<Area> areaCommand { get; set; } private ObservableCollection<Country> countries; public ObservableCollection<Country> Countries
{
get { return countries; }
set { countries = value; RaisePropertyChanged(); }
} private ObservableCollection<Sheng> shengs; public ObservableCollection<Sheng> Shengs
{
get { return shengs; }
set { shengs = value; RaisePropertyChanged(); }
} private ObservableCollection<City> cities; public ObservableCollection<City> Cities
{
get { return cities; }
set { cities = value; RaisePropertyChanged(); }
} private ObservableCollection<Area> areas; public ObservableCollection<Area> Areas
{
get { return areas; }
set { areas = value; RaisePropertyChanged(); }
} public void InitDictionary()
{
Countries = new ObservableCollection<Country>();
Shengs = new ObservableCollection<Sheng>();
Cities = new ObservableCollection<City>();
Areas = new ObservableCollection<Area>(); Countries.Add(new Country() { DetailedCountry = "中国" });
Countries.Add(new Country() { DetailedCountry = "国外" }); AddressSheng.Add("湖北1", "中国");
AddressSheng.Add("湖北2", "中国");
AddressSheng.Add("湖北3", "中国");
AddressSheng.Add("湖北4", "中国");
AddressSheng.Add("湖北5", "中国");
AddressSheng.Add("湖北6", "中国");
AddressSheng.Add("湖北7", "中国");
AddressSheng.Add("湖北8", "中国");
AddressSheng.Add("纽约1", "国外");
AddressSheng.Add("纽约2", "国外");
AddressSheng.Add("纽约3", "国外");
AddressSheng.Add("纽约4", "国外");
AddressSheng.Add("纽约5", "国外");
AddressSheng.Add("纽约6", "国外");
AddressSheng.Add("纽约7", "国外");
AddressSheng.Add("纽约8", "国外"); AddressCity.Add("孝感", "湖北1");
AddressCity.Add("武汉", "湖北1");
AddressCity.Add("襄阳", "湖北1");
AddressCity.Add("十堰", "湖北1");
AddressCity.Add("仙桃", "湖北1");
AddressCity.Add("鄂州", "湖北2");
AddressCity.Add("黄冈", "湖北2");
AddressCity.Add("神农架", "湖北2");
AddressCity.Add("黄石", "湖北2");
AddressCity.Add("恩施", "湖北2");
AddressCity.Add("湖南1", "湖北3");
AddressCity.Add("湖南2", "湖北3");
AddressCity.Add("湖南3", "湖北3");
AddressCity.Add("湖南4", "湖北3");
AddressCity.Add("湖南5", "湖北3");
AddressCity.Add("湖南6", "湖北3");
AddressCity.Add("湖南7", "湖北3"); AddressArea.Add("孝感1", "孝感");
AddressArea.Add("孝感2", "孝感");
AddressArea.Add("孝感3", "孝感");
AddressArea.Add("孝感4", "孝感");
AddressArea.Add("孝感5", "孝感");
AddressArea.Add("孝感6", "孝感");
AddressArea.Add("孝感7", "孝感");
AddressArea.Add("孝感8", "孝感"); }
}

WPF 一种带有多个子集的类ComBox 解决方法的更多相关文章

  1. 16种C语言编译警告(Warning)类型的解决方法

    当编译程序发现程序中某个地方有疑问,可能有问题时就会给出一个警告信息.警告信息可能意味着程序中隐含的大错误,也可能确实没有问题.对于警告的正确处理方式应该是:尽可能地消除之.对于编译程序给出的每个警告 ...

  2. WebService中使用自定义类的解决方法(5种)

    转自:http://www.cnblogs.com/lxinxuan/archive/2007/05/24/758317.html Demo下载:http://files.cnblogs.com/lx ...

  3. CodedUI Test 测试WPF程序,无法获取控件属性值的解决方法

    注意注意!ItemStatus 在VS2010的CUIT里面是没有的!需要2013以上的版本才可使用. 公司新程序使用WPF制作,但使用CodedUI Test进行自动化测试的时候,很多控件抓取不到其 ...

  4. WPF 四种尺寸单位

    原文:WPF 四种尺寸单位 像素 px 默认单位可以省略 厘米cm 英寸 in 点 pt 1in = 96px 1cm=96/2.42px 1pt=96/72px

  5. WPF 平板上按钮点击不触发,鼠标点击触发的两种解决方法

    今天运行在windows平板上的程序,有个功能是弹出子窗体,点弹出窗体的关闭按钮,要点好几次才能触发.网上找了找,也有人与我类似的情形. 解决方法如下: public static void Disa ...

  6. WPF WebBrowser Memory Leak 问题及临时解决方法

    首先介绍一下内存泄漏(Memory Leak)的概念,内存泄露是指程序中已动态分配的堆内存由于某种原因未释放或者无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果. 最近在使用W ...

  7. Ubuntu几种常见乱码解决方法

    一.网页中的flash乱码:        ubuntu默认浏览器是Firefox,但是Ubuntu默认不安装像flash这种带版权的软件,所以当你浏览像youku或网页播放器时,这种带有 flash ...

  8. Spring Boot Maven Plugin打包异常及三种解决方法:Unable to find main class

    [背景]spring-boot项目,打包成可执行jar,项目内有两个带有main方法的类并且都使用了@SpringBootApplication注解(或者另一种情形:你有两个main方法并且所在类都没 ...

  9. PowerDesigner生成Oracle表名带有引号的解决方法

    PowerDesigner生成表名带有引号,如下: /*==============================================================*/ /* Tabl ...

随机推荐

  1. RocketMQ 简介

    本文根据阿里云 RocketMQ产品文档整理 地址:https://help.aliyun.com/document_detail/29532.html?userCode=qtldtin2 简介 Ro ...

  2. tree 中文(转)

    原文:http://www.dutor.net/index.php/2009/05/tree-cn-code/ 简介: tree命令可以以目录树的形式显示指定(默认显示这个文件系统)目录的所有文件夹和 ...

  3. 使用Spring中@Async注解实现异步调用

    异步调用? 在解释异步调用之前,我们先来看同步调用的定义:同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果. 异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕,继 ...

  4. MySQL 使用sql添加和创建用户

    用户管理 SQL 命令操作 用户表:mysql.user 本质:对mysql.user 表进行增删改查 -- ============== 用户管理 ============= -- 创建用户 -- ...

  5. 【Oracle】查询执行慢的sql

    查询执行最慢的sql select * from (select sa.SQL_TEXT, sa.SQL_FULLTEXT, sa.EXECUTIONS "执行次数", round ...

  6. bash5.0参考手册

    Bash Reference Manual a.summary-letter { text-decoration: none } blockquote.indentedblock { margin-r ...

  7. 5.2 Spring5源码--Spring AOP源码分析二

    目标: 1. 什么是AOP, 什么是AspectJ 2. 什么是Spring AOP 3. Spring AOP注解版实现原理 4. Spring AOP切面原理解析 一. 认识AOP及其使用 详见博 ...

  8. kubectl工具管理应用

    kubectl工具管理应用 创建一个pod [root@k8s-master ~]# kubectl run nginx --replicas=3 --labels="app=nginx-e ...

  9. oracle常见进度查询脚本

    1.查看索引创建进度 /* Formatted on 2019/8/20 下午 05:08:25 (QP5 v5.163.1008.3004) */ SELECT SID, DECODE (total ...

  10. JMS监听Oracle AQ

    该文档中,oracle版本为11g,jdk版本1.8,java项目为maven构建的springboot项目,springboot的版本为2.1.6,并使用了定时任务来做AQ监听的重连功能,解决由于外 ...